From 297bf251b44d8b52a31fe5a1aece330be9371ffe Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 06:23:55 +0000 Subject: [PATCH 001/132] google dent --- src/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index 1f376e55d4..a94e58b132 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -267,7 +267,7 @@ SyntaxElementMorph.prototype.setScale = function (num) { this.rounding = 9 * scale; this.edge = scale; this.flatEdge = scale * 0.5; - this.jag = 5 * scale; + this.jag = 1 * scale; this.inset = 6 * scale; this.hatHeight = 12 * scale; this.hatWidth = 70 * scale; From d01fe2c05b991886fb3147280cd717091a47664c Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 06:28:15 +0000 Subject: [PATCH 002/132] better looks --- src/blocks.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index a94e58b132..5b68c499f9 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -264,13 +264,13 @@ SyntaxElementMorph.prototype.setScale = function (num) { var scale = Math.min(Math.max(num, 1), 25); this.scale = scale; this.corner = 3 * scale; - this.rounding = 9 * scale; + this.rounding = 10 * scale; this.edge = scale; this.flatEdge = scale * 0.5; this.jag = 1 * scale; - this.inset = 6 * scale; - this.hatHeight = 12 * scale; - this.hatWidth = 70 * scale; + this.inset = 1 * scale; + this.hatHeight = 1 * scale; + this.hatWidth = 3 * scale; this.rfBorder = 3 * scale; this.minWidth = 0; this.dent = 8 * scale; @@ -292,8 +292,8 @@ SyntaxElementMorph.prototype.setScale = function (num) { this.minSnapDistance = 20; this.reporterDropFeedbackPadding = 10 * scale; this.labelContrast = 25; - this.activeHighlight = new Color(153, 255, 213); - this.errorHighlight = new Color(173, 15, 0); + this.activeHighlight = new Color(0, 255, 0); + this.errorHighlight = new Color(255, 0, 0); this.activeBlur = 20; this.activeBorder = 4; this.rfColor = new Color(120, 120, 120); From 20227c82ba650ba08a46a188f65f7d1d606d5341 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 06:37:20 +0000 Subject: [PATCH 003/132] fix --- src/blocks.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 5b68c499f9..adb4c73dcc 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -267,13 +267,13 @@ SyntaxElementMorph.prototype.setScale = function (num) { this.rounding = 10 * scale; this.edge = scale; this.flatEdge = scale * 0.5; - this.jag = 1 * scale; - this.inset = 1 * scale; + this.jag = 1 ; + this.inset = 1; this.hatHeight = 1 * scale; this.hatWidth = 3 * scale; this.rfBorder = 3 * scale; this.minWidth = 0; - this.dent = 8 * scale; + this.dent = 1; this.bottomPadding = 3 * scale; this.cSlotPadding = 4 * scale; this.typeInPadding = scale; From b5117a5ef79a640216008701fffa0cc02046695d Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 06:44:53 +0000 Subject: [PATCH 004/132] to block --- src/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index adb4c73dcc..b3e44ee7e2 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -6967,7 +6967,7 @@ CommandBlockMorph.prototype.drawBottomDentEdge = function (ctx, x, y) { ctx.strokeStyle = lowerGradient; ctx.beginPath(); ctx.moveTo(indent + shift, y + this.corner - shift); - ctx.lineTo(indent + this.dent, y + this.corner - shift); + ctx.moveTo(indent + this.dent, y + this.corner - shift); ctx.stroke(); rightGradient = ctx.createLinearGradient( From c327c5c94451eb013763bd89de7cfc7efdd82753 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 06:47:42 +0000 Subject: [PATCH 005/132] cap all --- src/blocks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index b3e44ee7e2..9a1f2b1fc7 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -6944,14 +6944,14 @@ CommandBlockMorph.prototype.drawBottomDentEdge = function (ctx, x, y) { ctx.strokeStyle = upperGradient; ctx.beginPath(); ctx.moveTo(this.corner, y - shift); - if (this.isStop()) { + if (true) { ctx.lineTo(this.width() - this.corner, y - shift); } else { ctx.lineTo(x + this.corner + this.inset - shift, y - shift); } ctx.stroke(); - if (this.isStop()) { // draw straight bottom edge + if (true) { // draw straight bottom edge return null; } From 24c0cafbb9523d7866b3ecd62cc750af0515df9d Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 06:52:06 +0000 Subject: [PATCH 006/132] commit --- src/blocks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 9a1f2b1fc7..fc833fd07c 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -6825,7 +6825,7 @@ CommandBlockMorph.prototype.outlinePath = function(ctx, inset) { false ); - if (!this.isStop()) { + if (false) { ctx.lineTo(this.width() - this.corner, bottom - inset); ctx.lineTo(this.corner * 3 + this.inset + this.dent, bottom - inset); ctx.lineTo(indent + this.dent, bottom + this.corner - inset); @@ -6901,7 +6901,7 @@ CommandBlockMorph.prototype.drawTopDentEdge = function (ctx, x, y) { ctx.strokeStyle = leftGradient; ctx.beginPath(); - ctx.moveTo(x + this.corner + this.inset, y + shift); + ctx.lineTo(this.width() - this.corner, y - shift); ctx.lineTo(indent, y + this.corner + shift); ctx.stroke(); From 8b4f879902199b7707e0d865e9b2b6375ccd904d Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 06:55:38 +0000 Subject: [PATCH 007/132] commit --- src/blocks.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index fc833fd07c..95e23c8f4d 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -6794,11 +6794,13 @@ CommandBlockMorph.prototype.outlinePath = function(ctx, inset) { ); // top dent: - ctx.lineTo(this.corner + this.inset, inset); - ctx.lineTo(indent, this.corner + inset); - ctx.lineTo(indent + this.dent, this.corner + inset); - ctx.lineTo(this.corner * 3 + this.inset + this.dent, inset); - ctx.lineTo(this.width() - this.corner, inset); + if(false){ + ctx.lineTo(this.corner + this.inset, inset); + ctx.lineTo(indent, this.corner + inset); + ctx.lineTo(indent + this.dent, this.corner + inset); + ctx.lineTo(this.corner * 3 + this.inset + this.dent, inset); + ctx.lineTo(this.width() - this.corner, inset); + } // top right: ctx.arc( @@ -6882,10 +6884,10 @@ CommandBlockMorph.prototype.drawTopDentEdge = function (ctx, x, y) { ctx.strokeStyle = upperGradient; ctx.beginPath(); - ctx.moveTo( + /*ctx.moveTo( x + this.corner * 3 + this.inset + this.dent + shift, y + shift - ); + );*/ ctx.lineTo(this.width() - this.corner, y + shift); ctx.stroke(); From d0c4101a8af1fd74b127685ed549f78181162e82 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 15:13:57 +0000 Subject: [PATCH 008/132] commit --- src/blocks.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 95e23c8f4d..bfee19acd0 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -6876,11 +6876,6 @@ CommandBlockMorph.prototype.drawTopDentEdge = function (ctx, x, y) { upperGradient.addColorStop(0, this.cachedClrBright); upperGradient.addColorStop(1, this.cachedClr); - ctx.strokeStyle = upperGradient; - ctx.beginPath(); - ctx.moveTo(this.corner, y + shift); - ctx.lineTo(x + this.corner + this.inset, y + shift); - ctx.stroke(); ctx.strokeStyle = upperGradient; ctx.beginPath(); @@ -6906,6 +6901,9 @@ CommandBlockMorph.prototype.drawTopDentEdge = function (ctx, x, y) { ctx.lineTo(this.width() - this.corner, y - shift); ctx.lineTo(indent, y + this.corner + shift); ctx.stroke(); + if (true) { // draw straight bottom edge + return null; + } lowerGradient = ctx.createLinearGradient( 0, From a5bcafbc2edc4b6888220986333fd7125ff90c49 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 15:16:27 +0000 Subject: [PATCH 009/132] commit --- src/blocks.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index bfee19acd0..eddf1a99e7 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -6896,14 +6896,14 @@ CommandBlockMorph.prototype.drawTopDentEdge = function (ctx, x, y) { leftGradient.addColorStop(0, this.cachedClr); leftGradient.addColorStop(1, this.cachedClrBright); + if (true) { // draw straight bottom edge + return null; + } ctx.strokeStyle = leftGradient; ctx.beginPath(); ctx.lineTo(this.width() - this.corner, y - shift); ctx.lineTo(indent, y + this.corner + shift); ctx.stroke(); - if (true) { // draw straight bottom edge - return null; - } lowerGradient = ctx.createLinearGradient( 0, From 73b796f46a3c38d4e7fe92a1900178e8f99f1811 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 15:21:17 +0000 Subject: [PATCH 010/132] commit --- src/blocks.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index eddf1a99e7..0b9e173615 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -6879,10 +6879,10 @@ CommandBlockMorph.prototype.drawTopDentEdge = function (ctx, x, y) { ctx.strokeStyle = upperGradient; ctx.beginPath(); - /*ctx.moveTo( - x + this.corner * 3 + this.inset + this.dent + shift, + ctx.moveTo( + x + this.corner, y + shift - );*/ + ); ctx.lineTo(this.width() - this.corner, y + shift); ctx.stroke(); From ad6bead66fb942060e445ee0258660c7a77bd0a9 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 17:27:51 +0000 Subject: [PATCH 011/132] commit --- src/blocks.js | 85 +++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 0b9e173615..020ea87c2c 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -7187,42 +7187,42 @@ HatBlockMorph.prototype.outlinePath = function(ctx, inset) { bottom = this.height() - this.corner, bottomCorner = this.height() - this.corner * 2, radius = Math.max(this.corner - inset, 0), - s = this.hatWidth, - h = this.hatHeight, - r = ((4 * h * h) + (s * s)) / (8 * h), - a = degrees(4 * Math.atan(2 * h / s)), - sa = a / 2, - sp = Math.min(s * 1.7, this.width() - this.corner); + pos = this.position(); - // top arc: - ctx.moveTo(inset, h + this.corner); + // top left: ctx.arc( - s / 2, - r, - r, - radians(-sa - 90), + this.corner*2, + this.corner*2, + radius, + radians(-180), radians(-90), false ); - ctx.bezierCurveTo( - s, - 0, - s, - h, - sp, - h - ); + + // top dent: + if (false) { + ctx.lineTo(this.corner + this.inset, inset); + ctx.lineTo(indent, this.corner + inset); + ctx.lineTo(indent + this.dent, this.corner + inset); + ctx.lineTo(this.corner * 3 + this.inset + this.dent, inset); + ctx.lineTo(this.width() - this.corner, inset); + } // top right: ctx.arc( - this.width() - this.corner, - h + this.corner, + this.width() - this.corner*2, + this.corner*2, radius, radians(-90), radians(-0), false ); + // C-Slots + this.cSlots().forEach(slot => { + slot.outlinePath(ctx, inset, slot.position().subtract(pos)); + }); + // bottom right: ctx.arc( this.width() - this.corner, @@ -7233,7 +7233,7 @@ HatBlockMorph.prototype.outlinePath = function(ctx, inset) { false ); - if (!this.isStop()) { + if (false) { ctx.lineTo(this.width() - this.corner, bottom - inset); ctx.lineTo(this.corner * 3 + this.inset + this.dent, bottom - inset); ctx.lineTo(indent + this.dent, bottom + this.corner - inset); @@ -7265,14 +7265,17 @@ HatBlockMorph.prototype.drawLeftEdge = function (ctx) { ctx.strokeStyle = gradient; ctx.beginPath(); - ctx.moveTo(shift, this.hatHeight + shift); + ctx.moveTo(shift, this.corner); ctx.lineTo(shift, this.height() - this.corner * 2 - shift); ctx.stroke(); }; HatBlockMorph.prototype.drawRightEdge = function (ctx) { var shift = this.edge * 0.5, + cslots = this.cSlots(), + top = this.top(), x = this.width(), + y, gradient; gradient = ctx.createLinearGradient(x - this.edge, 0, x, 0); @@ -7282,10 +7285,22 @@ HatBlockMorph.prototype.drawRightEdge = function (ctx) { ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; ctx.lineCap = 'round'; - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(x - shift, this.corner + this.hatHeight + shift); + + if (cslots.length) { + ctx.beginPath(); + ctx.moveTo(x - shift, this.corner + shift); + cslots.forEach(slot => { + y = slot.top() - top; + ctx.lineTo(x - shift, y); + ctx.stroke(); + ctx.beginPath(); + ctx.moveTo(x - shift, y + slot.height()); + }); + } else { + ctx.beginPath(); + ctx.moveTo(x - shift, this.corner + shift); + } ctx.lineTo(x - shift, this.height() - this.corner * 2); ctx.stroke(); }; @@ -10487,22 +10502,6 @@ CSlotMorph.prototype.outlinePath = function (ctx, inset, offset) { this.width() - this.corner + ox, this.corner + oy - inset ); - ctx.lineTo( - (this.inset * 2) + (this.corner * 3) + this.dent + ox, - this.corner + oy - inset - ); - ctx.lineTo( - (this.inset * 2) + (this.corner * 2) + this.dent + ox, - this.corner * 2 + oy - inset - ); - ctx.lineTo( - (this.inset * 2) + (this.corner * 2) + ox, - this.corner * 2 + oy - inset - ); - ctx.lineTo( - (this.inset * 2) + this.corner + ox, - this.corner + oy - inset - ); ctx.lineTo( this.inset + this.corner + ox, this.corner + oy - inset From f066970c99a4c74353bb217bd9da1297de7ab293 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 18:13:20 +0000 Subject: [PATCH 012/132] commit --- src/blocks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 020ea87c2c..77dff0550d 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -7182,7 +7182,7 @@ HatBlockMorph.prototype.reify = function () { // HatBlockMorph drawing: -HatBlockMorph.prototype.outlinePath = function(ctx, inset) { +/*HatBlockMorph.prototype.outlinePath = function(ctx, inset) { var indent = this.corner * 2 + this.inset, bottom = this.height() - this.corner, bottomCorner = this.height() - this.corner * 2, @@ -7353,7 +7353,7 @@ HatBlockMorph.prototype.drawTopLeftEdge = function (ctx) { ); ctx.lineTo(this.width() - this.corner, h + shift); ctx.stroke(); -}; +};*/ // ReporterBlockMorph ////////////////////////////////////////////////// From 307b3287d1a77133d09c2fcde60317596191e664 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 18:29:12 +0000 Subject: [PATCH 013/132] commit --- src/blocks.js | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 77dff0550d..7227c320c6 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -10118,46 +10118,6 @@ CommandSlotMorph.prototype.drawEdges = function (ctx) { ); ctx.stroke(); - // dent bottom - lowerGradient = ctx.createLinearGradient( - 0, - this.corner, - 0, - this.corner + edge - ); - lowerGradient.addColorStop(0, this.cachedClr); - lowerGradient.addColorStop(1, this.cachedClrDark); - - ctx.strokeStyle = lowerGradient; - ctx.beginPath(); - ctx.moveTo(indent + edge + rf * 2 + shift, this.corner + shift); - ctx.lineTo( - indent + edge + rf * 2 + (dent - rf * 2), - this.corner + shift - ); - ctx.stroke(); - - // dent right edge - rightGradient = ctx.createLinearGradient( - indent + edge + rf * 2 + (dent - rf * 2) - shift, - this.corner, - indent + edge + rf * 2 + (dent - rf * 2) + shift * 0.7, - this.corner + shift + shift * 0.7 - ); - rightGradient.addColorStop(0, this.cachedClr); - rightGradient.addColorStop(1, this.cachedClrDark); - - ctx.strokeStyle = rightGradient; - ctx.beginPath(); - ctx.moveTo( - indent + edge + rf * 2 + (dent - rf * 2), - this.corner + shift - ); - ctx.lineTo( - indent + edge + rf * 2 + (dent - rf * 2) + this.corner, - shift - ); - ctx.stroke(); // upper edge (right side) ctx.strokeStyle = upperGradient; From 33afbf37554e56e3151500bb46febda867becd08 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 19:01:28 +0000 Subject: [PATCH 014/132] commit --- src/blocks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 7227c320c6..311508439b 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -10590,10 +10590,10 @@ CSlotMorph.prototype.drawTopEdge = function (ctx, x, y) { ctx.strokeStyle = rightGradient; ctx.beginPath(); - ctx.moveTo( + /*ctx.moveTo( x + this.inset + (this.corner * 2) + this.dent, y + this.corner - shift - ); + );*/ ctx.lineTo( x + this.corner * 3 + this.inset + this.dent, y - shift From 3d9b1337e7f88849c9bf29a1895a1dd7add6e5e2 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 19:49:08 +0000 Subject: [PATCH 015/132] allow bottom blocks --- src/blocks.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 311508439b..5625711037 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -2987,7 +2987,7 @@ BlockMorph.uber = SyntaxElementMorph.prototype; // BlockMorph preferences settings: BlockMorph.prototype.isCachingInputs = true; -BlockMorph.prototype.zebraContrast = 40; // alternating color brightness +BlockMorph.prototype.zebraContrast = 0; // alternating color brightness // BlockMorph sound feedback: @@ -6477,14 +6477,14 @@ CommandBlockMorph.prototype.closestAttachTarget = function (newParent) { ); } } - if (!bottomBlock.isStop()) { + //if (!bottomBlock.isStop()) { ref.push( { point: bottomBlock.bottomAttachPoint(), loc: 'bottom' } ); - } + //} this.allAttachTargets(target).forEach(eachTarget => ref.forEach(eachRef => { // match: either both locs are 'wrap' or both are different, From 26e72d5d8a24d3444d8573e20a2d5a19244c0493 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 20:04:52 +0000 Subject: [PATCH 016/132] updrade foreverloop --- src/blocks.js | 4 ++-- src/objects.js | 2 +- src/threads.js | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 5625711037..a3017def0b 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -6533,7 +6533,7 @@ CommandBlockMorph.prototype.snap = function (hand) { scripts.lastNextBlock = target.element.nextBlock(); target.element.nextBlock(this); } - if (this.isStop()) { + /*if (this.isStop()) { next = this.nextBlock(); if (next) { scripts.add(next); @@ -6546,7 +6546,7 @@ CommandBlockMorph.prototype.snap = function (hand) { affected.fixLayout(); } } - } + }*/ } else if (target.loc === 'top') { target.element.removeHighlight(); offsetY = this.bottomBlock().bottom() - this.bottom(); diff --git a/src/objects.js b/src/objects.js index 1645192dec..89f5419657 100644 --- a/src/objects.js +++ b/src/objects.js @@ -1112,7 +1112,7 @@ SpriteMorph.prototype.primitiveBlocks = function () { doForever: { type: 'command', category: 'control', - spec: 'forever %loop', + spec: 'forever', code: 'forever', src: `( (prim t doForever action) diff --git a/src/threads.js b/src/threads.js index f27969b430..455a94e219 100644 --- a/src/threads.js +++ b/src/threads.js @@ -1092,7 +1092,8 @@ Process.prototype.isAutoLambda = function (inputSlot) { 'doIfElse', 'doWarp', 'doFor', - 'doForEach' + 'doForEach', + 'reportBlocksNative' ].includes(inputSlot.parent?.selector)) { // special cases when overloading those primitives // with custom block definitions @@ -3133,7 +3134,7 @@ Process.prototype.doForever = function (body) { this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); if (body) { - this.pushContext(body.blockSequence()); + this.pushContext(this.nextBlock().blockSequence()); } this.pushContext(); }; From ae66f78f5fa9f18f035e5cb10ba9445a90984bbe Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 20:07:30 +0000 Subject: [PATCH 017/132] fix --- src/threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/threads.js b/src/threads.js index 455a94e219..7de61d83f9 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3134,7 +3134,7 @@ Process.prototype.doForever = function (body) { this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); if (body) { - this.pushContext(this.nextBlock().blockSequence()); + this.pushContext(this.nextBlock()); } this.pushContext(); }; From d16d134904cea4684d95b80792205c72b86aee55 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 20:09:41 +0000 Subject: [PATCH 018/132] fix again --- src/threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/threads.js b/src/threads.js index 7de61d83f9..bb9e1d36f8 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3133,7 +3133,7 @@ Process.prototype.doForever = function (body) { // (lambda) this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); - if (body) { + if (!body) { this.pushContext(this.nextBlock()); } this.pushContext(); From 61c05f1eac3dc2a8e284dcb966798befef22f826 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 20:14:01 +0000 Subject: [PATCH 019/132] fix forevr --- src/threads.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/threads.js b/src/threads.js index bb9e1d36f8..9b1c992ef6 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3133,8 +3133,8 @@ Process.prototype.doForever = function (body) { // (lambda) this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); - if (!body) { - this.pushContext(this.nextBlock()); + if (body) { + this.pushContext(body.blockSequence ? body.blockSequence() : body); } this.pushContext(); }; From d80da7354306694b6f85b9f2027ac2473c845bc4 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 20:16:40 +0000 Subject: [PATCH 020/132] fix --- src/threads.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/threads.js b/src/threads.js index 9b1c992ef6..dd66c4f573 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3133,9 +3133,7 @@ Process.prototype.doForever = function (body) { // (lambda) this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); - if (body) { this.pushContext(body.blockSequence ? body.blockSequence() : body); - } this.pushContext(); }; From 63f6d23662559390cb4d7da334ea6df9fb8bff8d Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 20:23:47 +0000 Subject: [PATCH 021/132] test --- src/threads.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/threads.js b/src/threads.js index dd66c4f573..6950ea51f7 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3133,7 +3133,11 @@ Process.prototype.doForever = function (body) { // (lambda) this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); - this.pushContext(body.blockSequence ? body.blockSequence() : body); + if (body) { + this.pushContext(body.blockSequence()); + }else { + this.pushContext(this.context.toBlock()); + } this.pushContext(); }; From b00b63ea28bff864996f7926f4d9deb19817f957 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 20:26:51 +0000 Subject: [PATCH 022/132] jr forever --- src/threads.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/threads.js b/src/threads.js index 6950ea51f7..ea023db5fd 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3133,11 +3133,8 @@ Process.prototype.doForever = function (body) { // (lambda) this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); - if (body) { - this.pushContext(body.blockSequence()); - }else { - this.pushContext(this.context.toBlock()); - } + + this.pushContext(this.context.toBlock()); this.pushContext(); }; From 4f85d3e7cc891974cbc91a1cb3ad1aabd9354227 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 20:30:26 +0000 Subject: [PATCH 023/132] fix --- src/threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/threads.js b/src/threads.js index ea023db5fd..0d18b91c1b 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3134,7 +3134,7 @@ Process.prototype.doForever = function (body) { this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); - this.pushContext(this.context.toBlock()); + this.pushContext(this.context); this.pushContext(); }; From d360b7b1ec75aeb713edc2cb8dc019052c3ed30d Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 20:36:56 +0000 Subject: [PATCH 024/132] fix --- src/threads.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/threads.js b/src/threads.js index 0d18b91c1b..e8d9b73e08 100644 --- a/src/threads.js +++ b/src/threads.js @@ -815,7 +815,9 @@ Process.prototype.evaluateBlock = function (block, argCount) { selector === 'reportVariadicAnd' || selector === 'doIf' || selector === 'reportIfElse' || - selector === 'doReport') { + selector === 'doReport'|| + selector === 'doForever' + ) { if (this.isCatchingErrors) { try { return this[selector](block); @@ -3134,7 +3136,7 @@ Process.prototype.doForever = function (body) { this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); - this.pushContext(this.context); + this.pushContext(body); this.pushContext(); }; From 98f3309190753c9f0b7e33c14578ddc36071bd57 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 20:39:47 +0000 Subject: [PATCH 025/132] fix --- src/threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/threads.js b/src/threads.js index e8d9b73e08..823c281048 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3136,7 +3136,7 @@ Process.prototype.doForever = function (body) { this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); - this.pushContext(body); + this.pushContext(new Context(this.context,body)); this.pushContext(); }; From 692a301093b14b3d562c5b000cb067b3ca8bc3e6 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 20:46:50 +0000 Subject: [PATCH 026/132] fix --- src/threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/threads.js b/src/threads.js index 823c281048..4df07ae4c5 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3136,7 +3136,7 @@ Process.prototype.doForever = function (body) { this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); - this.pushContext(new Context(this.context,body)); + this.pushContext(this.reify(body,new List([]))); this.pushContext(); }; From 3eb66da204a5b621e5b7ea120d75aa68163d1c89 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 17 Aug 2024 20:54:35 +0000 Subject: [PATCH 027/132] fix --- src/threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/threads.js b/src/threads.js index 4df07ae4c5..a64033c9bc 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3136,7 +3136,7 @@ Process.prototype.doForever = function (body) { this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); - this.pushContext(this.reify(body,new List([]))); + this.pushContext(this.reify(body.nextBlock(),new List([]))); this.pushContext(); }; From 8f28815d1edd75294acafc94cf0709c34b308657 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sun, 18 Aug 2024 00:36:56 +0000 Subject: [PATCH 028/132] nice --- src/threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/threads.js b/src/threads.js index a64033c9bc..71ef741368 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3136,7 +3136,7 @@ Process.prototype.doForever = function (body) { this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); - this.pushContext(this.reify(body.nextBlock(),new List([]))); + this.pushContext(body.nextBlock().blockSequence()); this.pushContext(); }; From 4870acd09d62feb9c0ef62a783f0c7e65a71a3ab Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sun, 18 Aug 2024 00:42:44 +0000 Subject: [PATCH 029/132] perfect forever --- src/threads.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/threads.js b/src/threads.js index 71ef741368..3a3f1f02b9 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3135,8 +3135,9 @@ Process.prototype.doForever = function (body) { // (lambda) this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); - - this.pushContext(body.nextBlock().blockSequence()); + if (body){ + this.pushContext(body.nextBlock().blockSequence()); + } this.pushContext(); }; From 40b063d6116d26ac15ef648736f111229799d0a6 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sun, 18 Aug 2024 00:44:13 +0000 Subject: [PATCH 030/132] fix code cleaness --- src/threads.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/threads.js b/src/threads.js index 3a3f1f02b9..e2046cee10 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3128,7 +3128,8 @@ Process.prototype.doPauseAll = function () { // Process loop primitives -Process.prototype.doForever = function (body) { +Process.prototype.doForever = function (block) { + var body = block.nextBlock() // non-special-form version, requires the C-slot input to // be marked as non-unevaluated (applicative order), which makes it // return its plain nested block without reifying it into a Context @@ -3136,7 +3137,7 @@ Process.prototype.doForever = function (body) { this.context.inputs = []; // force re-evaluation of C-slot this.pushContext('doYield'); if (body){ - this.pushContext(body.nextBlock().blockSequence()); + this.pushContext(body.blockSequence()); } this.pushContext(); }; From 660e4a0cea832ecd846dc75f6658dbd9c334f756 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Mon, 19 Aug 2024 03:36:15 +0000 Subject: [PATCH 031/132] remove forever from list for convienence --- src/blocks.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index a3017def0b..162648860a 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -6623,7 +6623,6 @@ CommandBlockMorph.prototype.isStop = function () { return choice instanceof Array && choice[0].length < 12; } return ([ - 'doForever', 'doReport', 'removeClone', 'doSwitchToScene' From 735e2bb6a1b4638eb097259e07531afe6c5e8ba4 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Mon, 19 Aug 2024 06:29:39 +0000 Subject: [PATCH 032/132] add blocks --- src/blocks.js | 48 ++++++++++++++++++++++++++++++++++++++++++------ src/objects.js | 11 +++++++++++ src/threads.js | 8 ++++++++ 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 162648860a..ee6a427c9f 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -330,6 +330,11 @@ SyntaxElementMorph.prototype.labelParts = { type: 'input', tags: 'unevaluated' }, + '%StatInfo':{ + type: 'input', + tags: 'readonly', + menu:'statinfoMenu' + }, '%dir': { type: 'input', tags: 'numeric', @@ -10839,10 +10844,6 @@ InputSlotMorph.prototype.setContents = function (data) { } if (isConstant) { - // migrate old "any" constants - if (dta[0] === 'any') { - dta[0] = 'random'; - } if (dta[0] === '__shout__go__') { this.symbol = this.labelPart('$greenflag'); this.add(this.symbol); @@ -10982,9 +10983,9 @@ InputSlotMorph.prototype.menuFromDict = function ( return; } } - if (!noEmptyOption) { + /*if (!noEmptyOption) { menu.addItem(' ', null); - } + }*/ for (key in choices) { if (Object.prototype.hasOwnProperty.call(choices, key)) { if (key[0].split('').every(c => c === '~')) { @@ -11069,6 +11070,41 @@ InputSlotMorph.prototype.menuFromDict = function ( return menu; }; +InputSlotMorph.prototype.statinfoMenu = function(){ + return { + ObjType:"ObjType", + size:"size", + blksize:"blksize", + blocks:"blocks", + time:{ + atimeNs:"atimeNs", + mtimeNs:"mtimeNs", + ctimeNs:"ctimeNs", + birthtimeNs:"birthtimeNs", + }, + device:{ + id:"dev", + "file device number":"rdev", + bavail:"bavail", + "bfree":"bfree", + blocks:"blocks", + bsize:"bsize", + fs:{ + ffree:"ffree", + file:"file", + type:"type", + } + }, + INode:"ino", + permissions:"mode", + "hardlink count🧱🔗#":"nlink", + owner:{ + user:"uid", + group:"gid", + } + } +} + // InputSlotMorph special drop-down menus: // Note each function returning a drop-down menu // must accept a Boolean parameter enabling its diff --git a/src/objects.js b/src/objects.js index 89f5419657..ed9e5ba923 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2263,6 +2263,12 @@ SpriteMorph.prototype.primitiveBlocks = function () { spec: 'video %vid on %self', defaults: [['motion'], ['myself']], code: 'video' + }, + getStatInfo:{ + type:'command', + category: 'other', + spec: '$magnifyingGlass-2 %s %StatInfo', + code: 'filestat' } }; }; @@ -3765,6 +3771,8 @@ SpriteMorph.prototype.blockTemplates = function ( blocks.push(block('reportFrameCount')); blocks.push(block('reportYieldCount')); } + blocks.push('-') + blocks.push(block("getStatInfo")); } else if (category === 'operators') { blocks.push(block('reifyScript')); @@ -10917,6 +10925,9 @@ StageMorph.prototype.blockTemplates = function ( blocks.push(block('reportFrameCount')); blocks.push(block('reportYieldCount')); } + + blocks.push('-') + blocks.push(block("getStatInfo")); } if (category === 'operators') { diff --git a/src/threads.js b/src/threads.js index e2046cee10..62c56fa5d7 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3072,6 +3072,14 @@ Process.prototype.doSetGlobalFlag = function (name, bool) { } }; +Process.prototype.getStatInfo = async function (object,info,callback) { + var api = require('file') + if (typeof(object) == "number") { + this.evaluate(callback,new List([(await api.IDToObject(object))[info]]));return + } + this.evaluate(callback, new List([(await api.getStat(object))[info]])) +} + Process.prototype.reportGlobalFlag = function (name) { var stage = this.homeContext.receiver.parentThatIsA(StageMorph); name = this.inputOption(name); From a8c18f3c5f43a5d2cef24425c5a67aebf661e04e Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Mon, 19 Aug 2024 06:33:02 +0000 Subject: [PATCH 033/132] fix --- src/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index ee6a427c9f..dc7b5a6e83 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -332,7 +332,7 @@ SyntaxElementMorph.prototype.labelParts = { }, '%StatInfo':{ type: 'input', - tags: 'readonly', + tags: 'read-only', menu:'statinfoMenu' }, '%dir': { From 7075d38a9b185bd91144a240b9c4433d42aadf8b Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Mon, 19 Aug 2024 06:37:28 +0000 Subject: [PATCH 034/132] fix --- src/objects.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objects.js b/src/objects.js index ed9e5ba923..b98540eb42 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2267,7 +2267,7 @@ SpriteMorph.prototype.primitiveBlocks = function () { getStatInfo:{ type:'command', category: 'other', - spec: '$magnifyingGlass-2 %s %StatInfo', + spec: '$magnifyingGlass-2 %s %StatInfo %cmdRing', code: 'filestat' } }; From ad13f81327cff3b1f8ad90f2d0aeda19842a36e5 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 07:45:01 +0000 Subject: [PATCH 035/132] fix --- snap.html | 1 + src/blocks.js | 5 +++++ src/nativetypes.js | 31 +++++++++++++++++++++++++++++++ src/objects.js | 22 ++++++++++++++++++++++ src/threads.js | 24 +++++++++++++++++++++++- 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/nativetypes.js diff --git a/snap.html b/snap.html index 4ff841a830..877857ccbe 100755 --- a/snap.html +++ b/snap.html @@ -37,6 +37,7 @@ + Throw an error. Makes a red halo appear around the script that runs it, with the input text shown in a speech balloon next to the script, just like any Snap! error. This is useful to put in the second script of SAFELY TRY after some other instructions to undo the partial work of the first script.
pt:lança o erro _
Catch errors in a reporter. Evaluates its first input. If that expression successfully reports a value, this block reports that value. If the expression causes a Snap! error, then the final input slot is evaluated with the text of what would have been the error message in variable ERROR. SAFELY TRY then reports the value of that final expression. Sometimes you'll want to throw an error in the final expression. You can put an ERROR block inside a CALL block to do that.
ca:prova de forma segura reportant _ i si _ reportant _ err
\ No newline at end of file +Catch errors. Runs the first script. If it succeeds, nothing else happens. But if it has an error (something that would otherwise result in a red halo around the block), then the second script is run, with the text of the error message that would have been shown in the variable ERROR.
pt:tenta executar _ e, em caso de erro _ , executa _ ca:prova de forma segura _ i si _ _
Catch errors in a reporter. Evaluates its first input. If that expression successfully reports a value, this block reports that value. If the expression causes a Snap! error, then the final input slot is evaluated with the text of what would have been the error message in variable ERROR. SAFELY TRY then reports the value of that final expression. Sometimes you'll want to throw an error in the final expression. You can put an ERROR block inside a CALL block to do that.
ca:prova de forma segura reportant _ i si _ reportant _ err
Throw an error. Makes a red halo appear around the script that runs it, with the input text shown in a speech balloon next to the script, just like any Snap! error. This is useful to put in the second script of SAFELY TRY after some other instructions to undo the partial work of the first script.
pt:lança o erro _
Error
\ No newline at end of file From 29dea9e6be5a56235db3ce7d27f5895864ed10b7 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:20:17 +0000 Subject: [PATCH 046/132] fix --- src/objects.js | 4 ++-- src/threads.js | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/objects.js b/src/objects.js index 52f10e0512..4b2f0dd8fd 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2265,9 +2265,9 @@ SpriteMorph.prototype.primitiveBlocks = function () { code: 'video' }, getStatInfo:{ - type:'command', + type:'reporter', category: 'other', - spec: '$magnifyingGlass-2 %s %StatInfo %cmdRing', + spec: 'stat fs object %s %StatInfo', code: 'filestat' }, newPromise:{ diff --git a/src/threads.js b/src/threads.js index 6b8b4e3a4d..fd42768507 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3112,11 +3112,9 @@ Process.prototype.doSetGlobalFlag = function (name, bool) { Process.prototype.getStatInfo = async function (object,info,callback) { var api = require('file') if (typeof(object) == "number") { - this.evaluate(callback,new List([(await api.IDToObject(object))[info]]));return + return (await api.IDToObject(object))[info] } - (await api.getStat(object,(e)=>{ - - })) + return (await api.getStat(object)[info]) } From 5c9b02bd9b55c9fee27ff0461609b36bd9d94cb6 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 20:14:12 +0000 Subject: [PATCH 047/132] fix --- src/morphic.js | 10 +++++----- src/objects.js | 10 ++++++++-- src/threads.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/morphic.js b/src/morphic.js index 33df7f5b1d..edeae2f8ce 100644 --- a/src/morphic.js +++ b/src/morphic.js @@ -8151,7 +8151,7 @@ MenuMorph.prototype.createLabel = function () { 'center' ); text.alignment = 'center'; - text.color = WHITE; + text.color = this.color; text.backgroundColor = this.borderColor; text.fixLayout(); this.label = new BoxMorph(3, 0); @@ -8178,8 +8178,8 @@ MenuMorph.prototype.createItems = function () { this.edge = MorphicPreferences.isFlat ? 0 : 5; this.border = MorphicPreferences.isFlat ? 1 : 2; } - this.color = WHITE; - this.borderColor = new Color(60, 60, 60); + this.color = new Color(20, 20, 25); + this.borderColor = new Color(125,125,125); this.setExtent(new Point(0, 0)); y = 2; @@ -9887,7 +9887,7 @@ TriggerMorph.prototype.init = function ( this.fontStyle = fontStyle || 'sans-serif'; this.highlightColor = new Color(192, 192, 192); this.pressColor = new Color(128, 128, 128); - this.labelColor = labelColor || new Color(0, 0, 0); + this.labelColor = labelColor || WHITE; this.labelBold = labelBold || false; this.labelItalic = labelItalic || false; this.userState = 'normal'; // 'highlight', 'pressed' @@ -9896,7 +9896,7 @@ TriggerMorph.prototype.init = function ( TriggerMorph.uber.init.call(this); // override inherited properites: - this.color = WHITE; + this.color = new Color(20, 20, 25); this.createLabel(); }; diff --git a/src/objects.js b/src/objects.js index 4b2f0dd8fd..ff0e4d853e 100644 --- a/src/objects.js +++ b/src/objects.js @@ -192,12 +192,12 @@ SpriteMorph.prototype.blockColorFor = function (category) { SpriteMorph.prototype.paletteColor = new Color(55, 55, 55); SpriteMorph.prototype.paletteTextColor = new Color(230, 230, 230); SpriteMorph.prototype.sliderColor - = SpriteMorph.prototype.paletteColor.lighter(30); + = SpriteMorph.prototype.paletteColor.lighter(10); SpriteMorph.prototype.isCachingPrimitives = true; SpriteMorph.prototype.enableNesting = true; SpriteMorph.prototype.enableFirstClass = true; -SpriteMorph.prototype.showingExtensions = false; +SpriteMorph.prototype.showingExtensions = true; SpriteMorph.prototype.useFlatLineEnds = false; SpriteMorph.prototype.penColorModel = 'hsv'; // or 'hsl' SpriteMorph.prototype.disableDraggingData = false; @@ -2287,6 +2287,12 @@ SpriteMorph.prototype.primitiveBlocks = function () { category: 'control', spec: '%ros catch %cmdRing', code: 'catch' + }, + Await: { + type: 'reporter', + category: 'control', + spec: 'await %ros', + code: 'await' } }; }; diff --git a/src/threads.js b/src/threads.js index fd42768507..36e8018138 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3117,6 +3117,35 @@ Process.prototype.getStatInfo = async function (object,info,callback) { return (await api.getStat(object)[info]) } +Process.prototype.Await = function (promise){ + if (!this.awaiting){ + this.value = void 0 + this.done = false + this.errored = false + promise.then((r) => { + this.value = r + this.done = true + }, (e) => { + this.value = e + this.done = true + this.errored = true + }) + } + this.awaiting = true + if (this.done) { + this.popContext(); + this.pushContext('doYield'); + if (this.errored) { + this.awaiting = false; + throw this.value + } + this.awaiting = false; + return this.value; + } + this.context.inputs = []; + this.pushContext('doYield'); + this.pushContext(); +} Process.prototype.promiseThen = function(promise,cmds){ From 62d01c0184b26f82e746e039906c3319625aac3e Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 20:35:26 +0000 Subject: [PATCH 048/132] fix --- src/morphic.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/morphic.js b/src/morphic.js index edeae2f8ce..65568b17c3 100644 --- a/src/morphic.js +++ b/src/morphic.js @@ -9885,8 +9885,8 @@ TriggerMorph.prototype.init = function ( this.schedule = null; // animation slot for displaying hints this.fontSize = fontSize || MorphicPreferences.menuFontSize; this.fontStyle = fontStyle || 'sans-serif'; - this.highlightColor = new Color(192, 192, 192); - this.pressColor = new Color(128, 128, 128); + this.highlightColor = new Color(255,255,255,16); + this.pressColor = new Color(255,255,255,0x4f); this.labelColor = labelColor || WHITE; this.labelBold = labelBold || false; this.labelItalic = labelItalic || false; From 123034585760a92a41b148e204b5f84aad53b98f Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 20:40:44 +0000 Subject: [PATCH 049/132] fix --- src/morphic.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/morphic.js b/src/morphic.js index 65568b17c3..04662c4792 100644 --- a/src/morphic.js +++ b/src/morphic.js @@ -9885,8 +9885,8 @@ TriggerMorph.prototype.init = function ( this.schedule = null; // animation slot for displaying hints this.fontSize = fontSize || MorphicPreferences.menuFontSize; this.fontStyle = fontStyle || 'sans-serif'; - this.highlightColor = new Color(255,255,255,16); - this.pressColor = new Color(255,255,255,0x4f); + this.highlightColor = new Color(255, 255, 255).mixed(16 / 255, new Color(20, 20, 25)); + this.pressColor = new Color(255, 255, 255).mixed(0x4f / 255, new Color(20, 20, 25)); this.labelColor = labelColor || WHITE; this.labelBold = labelBold || false; this.labelItalic = labelItalic || false; From b2f239e98e0769e316ee2169ba57b8334d6b85d7 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 20:45:36 +0000 Subject: [PATCH 050/132] fix --- src/morphic.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/morphic.js b/src/morphic.js index 04662c4792..0a3e71a618 100644 --- a/src/morphic.js +++ b/src/morphic.js @@ -9885,8 +9885,8 @@ TriggerMorph.prototype.init = function ( this.schedule = null; // animation slot for displaying hints this.fontSize = fontSize || MorphicPreferences.menuFontSize; this.fontStyle = fontStyle || 'sans-serif'; - this.highlightColor = new Color(255, 255, 255).mixed(16 / 255, new Color(20, 20, 25)); - this.pressColor = new Color(255, 255, 255).mixed(0x4f / 255, new Color(20, 20, 25)); + this.highlightColor = new Color(255, 255, 255).mixed(1 - (16 / 255), new Color(20, 20, 25)); + this.pressColor = new Color(255, 255, 255).mixed(1 - (0x4f / 255), new Color(20, 20, 25)); this.labelColor = labelColor || WHITE; this.labelBold = labelBold || false; this.labelItalic = labelItalic || false; From e0fa502b95ab8d4a841d6fd9be0955dd28b4bb40 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 20:53:08 +0000 Subject: [PATCH 051/132] fix --- src/morphic.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/morphic.js b/src/morphic.js index 0a3e71a618..43c4f8065c 100644 --- a/src/morphic.js +++ b/src/morphic.js @@ -9885,8 +9885,8 @@ TriggerMorph.prototype.init = function ( this.schedule = null; // animation slot for displaying hints this.fontSize = fontSize || MorphicPreferences.menuFontSize; this.fontStyle = fontStyle || 'sans-serif'; - this.highlightColor = new Color(255, 255, 255).mixed(1 - (16 / 255), new Color(20, 20, 25)); - this.pressColor = new Color(255, 255, 255).mixed(1 - (0x4f / 255), new Color(20, 20, 25)); + this.highlightColor = new Color(20, 20, 25).lighter(20); + this.pressColor = new Color(20, 20, 25).lighter(30); this.labelColor = labelColor || WHITE; this.labelBold = labelBold || false; this.labelItalic = labelItalic || false; From 3b6052d04baf84f90db7c5a51847df5105b951e2 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:17:13 +0000 Subject: [PATCH 052/132] good look --- src/blocks.js | 99 ++++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index df9e007872..342051c233 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -5308,30 +5308,33 @@ BlockMorph.prototype.render = function (ctx) { this.cachedClr = this.color.toString(); this.cachedClrBright = this.bright(); this.cachedClrDark = this.dark(); + var fill = this.color.copy() + fill.a = .5 + var cssfill = fill.toString(); if (MorphicPreferences.isFlat) { // draw the outline - ctx.fillStyle = this.cachedClrDark; + ctx.fillStyle = cssfill; ctx.beginPath(); this.outlinePath(ctx, 0); ctx.closePath(); ctx.fill(); // draw the inner filled shaped - ctx.fillStyle = this.cachedClr; + ctx.fillStyle = cssfill; ctx.beginPath(); this.outlinePath(ctx, this.flatEdge); ctx.closePath(); ctx.fill(); } else { // draw the flat shape - ctx.fillStyle = this.cachedClr; + ctx.fillStyle = cssfill; ctx.beginPath(); this.outlinePath(ctx, 0); ctx.closePath(); ctx.fill(); - // add 3D-Effect: + // add outline: this.drawEdges(ctx); } @@ -6881,8 +6884,8 @@ CommandBlockMorph.prototype.drawTopDentEdge = function (ctx, x, y) { 0, y + this.edge ); - upperGradient.addColorStop(0, this.cachedClrBright); - upperGradient.addColorStop(1, this.cachedClr); + upperGradient.addColorStop(0, this.color+""); + upperGradient.addColorStop(1, this.color+""); ctx.strokeStyle = upperGradient; @@ -6901,8 +6904,8 @@ CommandBlockMorph.prototype.drawTopDentEdge = function (ctx, x, y) { lgx, y ); - leftGradient.addColorStop(0, this.cachedClr); - leftGradient.addColorStop(1, this.cachedClrBright); + leftGradient.addColorStop(0, this.color+""); + leftGradient.addColorStop(1, this.color+""); if (true) { // draw straight bottom edge return null; @@ -6946,8 +6949,8 @@ CommandBlockMorph.prototype.drawBottomDentEdge = function (ctx, x, y) { 0, y ); - upperGradient.addColorStop(0, this.cachedClr); - upperGradient.addColorStop(1, this.cachedClrDark); + upperGradient.addColorStop(0, this.color+""); + upperGradient.addColorStop(1, this.color+""); ctx.strokeStyle = upperGradient; ctx.beginPath(); @@ -7020,8 +7023,8 @@ CommandBlockMorph.prototype.drawLeftEdge = function (ctx) { var shift = this.edge * 0.5, gradient = ctx.createLinearGradient(0, 0, this.edge, 0); - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; @@ -7043,8 +7046,8 @@ CommandBlockMorph.prototype.drawRightEdge = function (ctx) { gradient; gradient = ctx.createLinearGradient(x - this.edge, 0, x, 0); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; @@ -7081,8 +7084,8 @@ CommandBlockMorph.prototype.drawTopLeftEdge = function (ctx) { this.corner, this.corner - this.edge ); - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; @@ -7116,8 +7119,8 @@ CommandBlockMorph.prototype.drawBottomRightEdge = function (ctx) { y, this.corner - this.edge ); - gradient.addColorStop(0, this.cachedClrDark); - gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; @@ -7725,8 +7728,8 @@ ReporterBlockMorph.prototype.drawEdgesOval = function (ctx) { h - r, r + this.edge ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrBright); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.arc( @@ -7748,8 +7751,8 @@ ReporterBlockMorph.prototype.drawEdgesOval = function (ctx) { r, r + this.edge ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.arc( @@ -7771,8 +7774,8 @@ ReporterBlockMorph.prototype.drawEdgesOval = function (ctx) { 0, this.edge ); - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(r - shift, shift); @@ -7788,8 +7791,8 @@ ReporterBlockMorph.prototype.drawEdgesOval = function (ctx) { r, r ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrBright); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.arc( @@ -7811,8 +7814,8 @@ ReporterBlockMorph.prototype.drawEdgesOval = function (ctx) { h - r, r ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.arc( @@ -7832,8 +7835,8 @@ ReporterBlockMorph.prototype.drawEdgesOval = function (ctx) { 0, h ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(r - shift, h - shift); @@ -7842,8 +7845,8 @@ ReporterBlockMorph.prototype.drawEdgesOval = function (ctx) { // left edge: straight vertical line gradient = ctx.createLinearGradient(0, 0, this.edge, 0); - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(shift, r); @@ -7852,8 +7855,8 @@ ReporterBlockMorph.prototype.drawEdgesOval = function (ctx) { // right edge: straight vertical line gradient = ctx.createLinearGradient(w - this.edge, 0, w, 0); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; if (cslots.length) { @@ -7899,8 +7902,8 @@ ReporterBlockMorph.prototype.drawEdgesDiamond = function (ctx) { r, 0 ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(shift, h2); @@ -7916,8 +7919,8 @@ ReporterBlockMorph.prototype.drawEdgesDiamond = function (ctx) { r, 0 ); - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(shift, h2); @@ -7932,8 +7935,8 @@ ReporterBlockMorph.prototype.drawEdgesDiamond = function (ctx) { 0, this.edge ); - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(r, shift); @@ -7947,8 +7950,8 @@ ReporterBlockMorph.prototype.drawEdgesDiamond = function (ctx) { // right vertical edge gradient = ctx.createLinearGradient(w - r - this.edge, 0, w - r, 0); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; @@ -7979,8 +7982,8 @@ ReporterBlockMorph.prototype.drawEdgesDiamond = function (ctx) { w + r, 0 ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(w - shift, h2); @@ -7995,8 +7998,8 @@ ReporterBlockMorph.prototype.drawEdgesDiamond = function (ctx) { w, 0 ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(w - r, h - shift); @@ -8012,8 +8015,8 @@ ReporterBlockMorph.prototype.drawEdgesDiamond = function (ctx) { 0, h ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.color+""); + gradient.addColorStop(1, this.color+""); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(r + shift, h - shift); From a3b86ef43dbdc59c042f1ad0578290b1d8b0333b Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:19:14 +0000 Subject: [PATCH 053/132] more transparent --- src/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index 342051c233..0c19402529 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -5309,7 +5309,7 @@ BlockMorph.prototype.render = function (ctx) { this.cachedClrBright = this.bright(); this.cachedClrDark = this.dark(); var fill = this.color.copy() - fill.a = .5 + fill.a = .25 var cssfill = fill.toString(); if (MorphicPreferences.isFlat) { From 9e8a6664a129b42ee0d6bfeb4c3ba1adc11f6e69 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:21:09 +0000 Subject: [PATCH 054/132] fix --- src/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index 0c19402529..7dde37c925 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -5309,7 +5309,7 @@ BlockMorph.prototype.render = function (ctx) { this.cachedClrBright = this.bright(); this.cachedClrDark = this.dark(); var fill = this.color.copy() - fill.a = .25 + fill.a = .1 var cssfill = fill.toString(); if (MorphicPreferences.isFlat) { From 450b28e9076f36464902a4ffb45aaefbbd0073b2 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:23:31 +0000 Subject: [PATCH 055/132] fix --- src/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index 7dde37c925..d3842bd8c8 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -5309,7 +5309,7 @@ BlockMorph.prototype.render = function (ctx) { this.cachedClrBright = this.bright(); this.cachedClrDark = this.dark(); var fill = this.color.copy() - fill.a = .1 + fill.a = 0 var cssfill = fill.toString(); if (MorphicPreferences.isFlat) { From 983905fc22558e0c0144a3ecc0aa391b958e05a6 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:31:18 +0000 Subject: [PATCH 056/132] fix --- src/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index d3842bd8c8..f91bfaf014 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -5309,7 +5309,7 @@ BlockMorph.prototype.render = function (ctx) { this.cachedClrBright = this.bright(); this.cachedClrDark = this.dark(); var fill = this.color.copy() - fill.a = 0 + fill.a = 0.1 var cssfill = fill.toString(); if (MorphicPreferences.isFlat) { From ebd5a95763c10e826a986db282c3064ce5326093 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:33:42 +0000 Subject: [PATCH 057/132] fix --- src/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index f91bfaf014..690cd0f6bb 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -5309,7 +5309,7 @@ BlockMorph.prototype.render = function (ctx) { this.cachedClrBright = this.bright(); this.cachedClrDark = this.dark(); var fill = this.color.copy() - fill.a = 0.1 + fill.a = 0.25 var cssfill = fill.toString(); if (MorphicPreferences.isFlat) { From bbd88f5f3f7da245082b35af067850dcdb3bd9a3 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:51:20 +0000 Subject: [PATCH 058/132] fix bool --- src/blocks.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 690cd0f6bb..f8f535b64a 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -12897,9 +12897,9 @@ BooleanSlotMorph.prototype.render = function (ctx) { this.cachedClr = this.color.toString(); this.cachedClrBright = this.bright(); this.cachedClrDark = this.dark(); - this.drawDiamond(ctx, this.progress); + //this.drawDiamond(ctx, this.progress); this.drawLabel(ctx); - this.drawKnob(ctx, this.progress); + //this.drawKnob(ctx, this.progress); }; BooleanSlotMorph.prototype.drawDiamond = function (ctx, progress) { @@ -13062,7 +13062,7 @@ BooleanSlotMorph.prototype.drawLabel = function (ctx) { return; } - if (this.isWide()) { // draw the full text label + { // draw the full text label text = this.textLabelExtent(); y = this.height() - (this.height() - text.y) / 2; if (this.value) { @@ -13354,7 +13354,7 @@ ArrowMorph.prototype.getRenderColor = function () { if (MorphicPreferences.isFlat) { return this.color; } - return SyntaxElementMorph.prototype.alpha > 0.5 ? this.color : WHITE; + return this.parent.color; } return this.color; }; From c4b4ce9452558d9fa6757e9693a8096d34de6658 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 22:58:28 +0000 Subject: [PATCH 059/132] fix --- src/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index f8f535b64a..eef1f31a9c 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -13080,7 +13080,7 @@ BooleanSlotMorph.prototype.drawLabel = function (ctx) { ctx.font = new StringMorph(null, this.fontSize, null, true).font(); ctx.textAlign = 'left'; ctx.textBaseline = 'bottom'; - ctx.fillStyle = 'rgb(255, 255, 255'; + ctx.fillStyle = this.value ? 'rgb(0, 255, 0)' : 'rgb(255, 0, 0)'; ctx.fillText( localize(this.value ? 'true' : 'false'), x, From 3bf1e700039b5a0f1423529390ada9475f544299 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:01:00 +0000 Subject: [PATCH 060/132] fix --- src/blocks.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index eef1f31a9c..9de4ed3fe4 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -12701,8 +12701,7 @@ BooleanSlotMorph.prototype.getSpec = function () { }; BooleanSlotMorph.prototype.isWide = function () { - return this.isStatic && ( - !(this.parent instanceof BlockMorph) || this.parent?.isPredicate); + return true }; // BooleanSlotMorph accessing: From cbb42164784d703325957fca35a734f0ab7efb6d Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:08:19 +0000 Subject: [PATCH 061/132] fix --- src/blocks.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 9de4ed3fe4..f5ae0ea73e 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -12701,7 +12701,7 @@ BooleanSlotMorph.prototype.getSpec = function () { }; BooleanSlotMorph.prototype.isWide = function () { - return true + return false }; // BooleanSlotMorph accessing: @@ -13064,11 +13064,7 @@ BooleanSlotMorph.prototype.drawLabel = function (ctx) { { // draw the full text label text = this.textLabelExtent(); y = this.height() - (this.height() - text.y) / 2; - if (this.value) { - x = this.height() / 2; - } else { - x = this.width() - (this.height() / 2) - text.x; - } + x = 0; ctx.save(); if (!MorphicPreferences.isFlat && useBlurredShadows) { ctx.shadowOffsetX = -shift; @@ -13080,8 +13076,11 @@ BooleanSlotMorph.prototype.drawLabel = function (ctx) { ctx.textAlign = 'left'; ctx.textBaseline = 'bottom'; ctx.fillStyle = this.value ? 'rgb(0, 255, 0)' : 'rgb(255, 0, 0)'; + if (this.value == null) { + ctx.fillStyle = 'rgb(0, 0, 255)' + } ctx.fillText( - localize(this.value ? 'true' : 'false'), + ((this.value == null)? "null" : (this.value ? 'true' : 'false')), x, y ); From da3c283fd0a96022eec22169d237ecc6806084b7 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:10:40 +0000 Subject: [PATCH 062/132] fix --- src/blocks.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index f5ae0ea73e..14030ab785 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -13057,9 +13057,6 @@ BooleanSlotMorph.prototype.drawLabel = function (ctx) { x, y = this.height() / 2; - if (this.isEmptySlot() || this.progress < 0) { - return; - } { // draw the full text label text = this.textLabelExtent(); From dc4683b72316d28be65561ede0f51eee8cc06f32 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:24:06 +0000 Subject: [PATCH 063/132] fix --- src/blocks.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/blocks.js b/src/blocks.js index 14030ab785..14d0ec2a88 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -10899,6 +10899,11 @@ InputSlotMorph.prototype.setContents = function (data) { } }; +InputSlotMorph.prototype.loop = function(...args){ + InputSlotMorph.uber.loop.apply(this,args) + this.alpha = 0 +} + InputSlotMorph.prototype.userSetContents = function (aStringOrFloat) { // enable copy-on-edit for inherited scripts var block = this.parentThatIsA(BlockMorph), From 4753bfd6bd5323d24d0bfa14f97d53eb8a997c36 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:29:31 +0000 Subject: [PATCH 064/132] fix --- src/blocks.js | 3607 +------------------------------------------------ 1 file changed, 2 insertions(+), 3605 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 14d0ec2a88..2657bca802 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -12138,7 +12138,7 @@ InputSlotMorph.prototype.unflash = function () { InputSlotMorph.prototype.render = function (ctx) { var borderColor, r; - + this.alpha = 0 // initialize my surface property if (this.cachedNormalColor) { // if flashing borderColor = this.color; @@ -13354,3607 +13354,4 @@ ArrowMorph.prototype.getRenderColor = function () { if (MorphicPreferences.isFlat) { return this.color; } - return this.parent.color; - } - return this.color; -}; - -// TextSlotMorph ////////////////////////////////////////////////////// - -/* - I am a multi-line input slot, primarily used in Snap's code-mapping - blocks. -*/ - -// TextSlotMorph inherits from InputSlotMorph: - -TextSlotMorph.prototype = new InputSlotMorph(); -TextSlotMorph.prototype.constructor = TextSlotMorph; -TextSlotMorph.uber = InputSlotMorph.prototype; - -// TextSlotMorph instance creation: - -function TextSlotMorph(text, isNumeric, choiceDict, isReadOnly) { - this.init(text, isNumeric, choiceDict, isReadOnly); -} - -TextSlotMorph.prototype.init = function ( - text, - isNumeric, - choiceDict, - isReadOnly -) { - var contents = new InputSlotTextMorph(''), - arrow = new ArrowMorph( - 'down', - 0, - Math.max(Math.floor(this.fontSize / 6), 1), - BLACK, - true - ); - - contents.fontSize = this.fontSize; - contents.fixLayout(); - - this.isUnevaluated = false; - this.choices = choiceDict || null; // object, function or selector - this.oldContentsExtent = contents.extent(); - this.isNumeric = isNumeric || false; - this.isReadOnly = isReadOnly || false; - this.minWidth = 0; // can be chaged for text-type inputs ("landscape") - this.constant = null; - - InputSlotMorph.uber.init.call(this, null, null, null, null, true); // sil. - this.color = WHITE; - this.add(contents); - this.add(arrow); - contents.isEditable = true; - contents.isDraggable = false; - contents.enableSelecting(); - this.setContents(text); - -}; - -// TextSlotMorph accessing: - -TextSlotMorph.prototype.getSpec = function () { - if (this.isNumeric) { - return '%mlt'; - } - return '%mlt'; // default -}; - -TextSlotMorph.prototype.contents = function () { - return detect( - this.children, - child => child instanceof TextMorph - ); -}; - -// TextSlotMorph events: - -TextSlotMorph.prototype.layoutChanged = function () { - this.fixLayout(); -}; - -// ColorSlotMorph ////////////////////////////////////////////////////// - -/* - I am an editable input slot for a color. Users can edit my color by - clicking on me, in which case a display a color gradient palette - and let the user select another color. Note that the user isn't - restricted to selecting a color from the palette, any color from - anywhere within the World can be chosen. - - my block spec is %clr - - evaluate() returns my color -*/ - -// ColorSlotMorph inherits from ArgMorph: - -ColorSlotMorph.prototype = new ArgMorph(); -ColorSlotMorph.prototype.constructor = ColorSlotMorph; -ColorSlotMorph.uber = ArgMorph.prototype; - -// ColorSlotMorph instance creation: - -function ColorSlotMorph(clr) { - this.init(clr); -} - -ColorSlotMorph.prototype.init = function (clr) { - ColorSlotMorph.uber.init.call(this); - this.alpha = 1; - this.setColor(clr || new Color(145, 26, 68)); -}; - -ColorSlotMorph.prototype.getSpec = function () { - return '%clr'; -}; - -// ColorSlotMorph color sensing: - -ColorSlotMorph.prototype.getUserColor = function () { - var myself = this, - world = this.world(), - hand = world.hand, - posInDocument = getDocumentPositionOf(world.worldCanvas), - mouseMoveBak = hand.processMouseMove, - mouseDownBak = hand.processMouseDown, - mouseUpBak = hand.processMouseUp, - pal = new ColorPaletteMorph(null, new Point( - this.fontSize * 16, - this.fontSize * 10 - )), - ctx; - world.add(pal); - pal.setPosition(this.bottomLeft().add(new Point(0, this.edge))); - - // cache the world surface property (its full image) - // to prevent memory issues from constantly generating - // huge canvasses and and reading back pixel data only once - // note: this optimization makes it hard / impossible for the - // user to "catch" and sample the color of moving sprites - // but without it Chrome crashes as of Fall 2023 - ctx = Morph.prototype.fullImage.call(world).getContext('2d'); - - hand.processMouseMove = function (event) { - var pos = hand.position(), - dta = ctx.getImageData(pos.x, pos.y, 1, 1).data; - hand.setPosition(new Point( - event.pageX - posInDocument.x, - event.pageY - posInDocument.y - )); - myself.setColor(new Color(dta[0], dta[1], dta[2])); - }; - - hand.processMouseDown = nop; - - hand.processMouseUp = function () { - pal.destroy(); - hand.processMouseMove = mouseMoveBak; - hand.processMouseDown = mouseDownBak; - hand.processMouseUp = mouseUpBak; - }; -}; - -// ColorSlotMorph events: - -ColorSlotMorph.prototype.mouseClickLeft = function () { - this.selectForEdit().getUserColor(); -}; - -// ColorSlotMorph evaluating: - -ColorSlotMorph.prototype.evaluate = function () { - return this.color; -}; - -// ColorSlotMorph drawing: - -ColorSlotMorph.prototype.fixLayout = function () { - // determine my extent - var side = this.fontSize + this.edge * 2 + this.typeInPadding * 2; - this.bounds.setWidth(side); - this.bounds.setHeight(side); -}; - -ColorSlotMorph.prototype.render = function (ctx) { - var borderColor; - - if (this.parent) { - borderColor = this.parent.color; - } else { - borderColor = new Color(120, 120, 120); - } - ctx.fillStyle = this.color.toString(); - - // cache my border colors - this.cachedClr = borderColor.toString(); - this.cachedClrBright = borderColor.lighter(this.contrast) - .toString(); - this.cachedClrDark = borderColor.darker(this.contrast).toString(); - - ctx.fillRect( - this.edge, - this.edge, - this.width() - this.edge * 2, - this.height() - this.edge * 2 - ); - if (!MorphicPreferences.isFlat) { - this.drawRectBorder(ctx); - } -}; - -ColorSlotMorph.prototype.drawRectBorder = - InputSlotMorph.prototype.drawRectBorder; - -// BlockHighlightMorph ///////////////////////////////////////////////// - -/* - I am a glowing halo around a block or stack of blocks indicating that - a script is currently active or has encountered an error. - I halso have an optional readout that can display a thread count - if more than one process shares the same script -*/ - -// BlockHighlightMorph inherits from Morph: - -BlockHighlightMorph.prototype = new Morph(); -BlockHighlightMorph.prototype.constructor = BlockHighlightMorph; -BlockHighlightMorph.uber = Morph.prototype; - -// BlockHighlightMorph instance creation: - -function BlockHighlightMorph() { - this.threadCount = 0; - this.init(); -} - -BlockHighlightMorph.prototype.init = function () { - BlockHighlightMorph.uber.init.call(this); - this.isCachingImage = true; -}; - -// BlockHighlightMorph thread count readout - -BlockHighlightMorph.prototype.readout = function () { - return this.children.length ? this.children[0] : null; -}; - -BlockHighlightMorph.prototype.updateReadout = function () { - var readout = this.readout(), - inset = useBlurredShadows && !MorphicPreferences.isFlat ? - SyntaxElementMorph.prototype.activeBlur * 0.4 - : SyntaxElementMorph.prototype.activeBorder * -2; - if (this.threadCount < 2) { - if (readout) { - readout.destroy(); - } - return; - } - if (readout) { - readout.changed(); - readout.contents = this.threadCount.toString(); - readout.fixLayout(); - readout.rerender(); - } else { - readout = new SpeechBubbleMorph( - this.threadCount.toString(), - this.color, // color, - null, // edge, - null, // border, - this.color.darker(), // borderColor, - null, // padding, - 1, // isThought - don't draw a hook - true // no shadow - faster - ); - this.add(readout); - } - readout.setPosition(this.position().add(inset)); -}; - -// MultiArgMorph /////////////////////////////////////////////////////// - -/* - I am an arity controlled list of input slots - - my block specs are - - %mult%x - where x is any single input slot - %inputs - for an additional text label 'with inputs' - - evaluation is handles by the interpreter -*/ - -// MultiArgMorph inherits from ArgMorph: - -MultiArgMorph.prototype = new ArgMorph(); -MultiArgMorph.prototype.constructor = MultiArgMorph; -MultiArgMorph.uber = ArgMorph.prototype; - -// MultiArgMorph instance creation: - -function MultiArgMorph( - slotSpec, - labelTxt, - min, - eSpec, - arrowColor, - labelColor, - shadowColor, - shadowOffset, - isTransparent, - infix, - collapse, - defaults, - group -) { - this.init( - slotSpec, - labelTxt, - min, - eSpec, - arrowColor, - labelColor, - shadowColor, - shadowOffset, - isTransparent, - infix, - collapse, - defaults, - group - ); -} - -MultiArgMorph.prototype.init = function ( - slotSpec, // string or array of type strings - labelTxt, // string or array of prefix labels - min, - eSpec, - arrowColor, - labelColor, - shadowColor, - shadowOffset, - isTransparent, - infix, - collapse, - defaults, - group -) { - var label, - collapseLabel, - arrows = new FrameMorph(), - initial = min || 0, - listSymbol, - leftArrow, - rightArrow, - i; - - this.slotSpec = slotSpec || '%s'; - this.labelText = labelTxt instanceof Array ? - labelTxt.map(each => localize(each || '')) - : localize(labelTxt || ''); - this.infix = infix || ''; - this.collapse = localize(collapse || ''); - this.defaultValue = defaults || null; - this.groupInputs = 1; - this.initialSlots = isNil(initial) ? 1 : initial ; - this.minInputs = this.infix ? 0 : initial; - this.maxInputs = 0; - this.elementSpec = eSpec || null; - this.labelColor = labelColor || null; - this.shadowColor = shadowColor || null; - this.shadowOffset = shadowOffset || null; - - // in case an input group spec is specified, initialize it - this.initGroup(group); - - this.canBeEmpty = true; - MultiArgMorph.uber.init.call(this); - - // MultiArgMorphs are transparent by default b/c of zebra coloring - this.alpha = isTransparent === false ? 1 : 0; - arrows.alpha = isTransparent === false ? 1 : 0; - - // collapse label text: - if (this.collapse) { - collapseLabel = this.labelPart(this.collapse); - this.add(collapseLabel); - collapseLabel.hide(); - } - - // label text: - if (this.labelText || (this.slotSpec === '%cs')) { - label = this.labelPart( - this.labelText instanceof Array ? - this.labelText[0] - : this.labelText - ); - this.add(label); - label.hide(); - } - - // left arrow: - leftArrow = new ArrowMorph( - 'left', // direction - fontHeight(this.fontSize), // size - Math.max(Math.floor(this.fontSize / 6), 1), // padding - arrowColor, - true // isLbl - ); - - // right arrow: - rightArrow = new ArrowMorph( - 'right', // direction - fontHeight(this.fontSize), // size - Math.max(Math.floor(this.fontSize / 6), 1), // padding - arrowColor, - true // isLbl - ); - - // list symbol: - // listSymbol = this.labelPart('$verticalEllipsis-0.98'); - - // alternative list symbol designs to contemplate in the future: - // listSymbol = this.labelPart('$listNarrow-0.9'); - - /* - listSymbol = this.labelPart('$listNarrow-.98'); - listSymbol.backgroundColor = new Color(255, 140, 0); // list color - */ - - // /* - // listSymbol = new SymbolMorph('listNarrow', this.fontSize * 0.8); - listSymbol = new SymbolMorph('verticalEllipsis', this.fontSize); - listSymbol.alpha = 0.5; - listSymbol.getRenderColor = function () { - // behave the same as arrows when fading the blocks - if (MorphicPreferences.isFlat) { - return this.color; - } - return SyntaxElementMorph.prototype.alpha > 0.5 ? this.color : WHITE; - }; - // */ - - // control panel: - arrows.add(leftArrow); - arrows.add(rightArrow); - arrows.add(listSymbol); - arrows.rerender(); - arrows.acceptsDrops = false; - - this.add(arrows); - - // create the initial number of inputs - for (i = 0; i < initial; i += 1) { - this.addInput(); - } -}; - -MultiArgMorph.prototype.initGroup = function (aBlockSpec) { - var groupSpec, - words, - isSlot = word => word.startsWith('%') && word.length > 1, - labels = [], - part = []; - if (aBlockSpec) { - // translate block spec - groupSpec = BlockMorph.prototype.localizeBlockSpec(aBlockSpec); - // determine input slot specs - words = groupSpec.split(' '); - this.slotSpec = words.filter(word => isSlot(word)); - // determine group size - this.groupInputs = this.slotSpec.length; - // determine label texts - words.forEach(word => { - if (isSlot(word)) { - labels.push(part); - part = []; - } else { - part.push(word); - } - }); - // only add a postfix if it's non-empty - if (part.some(any => any.length)) { - labels.push(part); - } - this.labelText = labels.map(arr => arr.join(' ')); - } -}; - -MultiArgMorph.prototype.collapseLabel = function () { - return this.collapse ? this.children[0] : null; -}; - -MultiArgMorph.prototype.label = function () { - return this.labelText ? - this.children[this.collapse ? 1 : 0] - : null; -}; - -MultiArgMorph.prototype.allLabels = function () { - // including infix labels - return this.children.filter(m => m instanceof BlockLabelMorph); -}; - -MultiArgMorph.prototype.arrows = function () { - return this.children[this.children.length - 1]; -}; - -MultiArgMorph.prototype.listSymbol = function () { - return this.arrows().children[2]; -}; - -MultiArgMorph.prototype.getSpec = function () { - return '%mult' + this.slotSpec; -}; - -MultiArgMorph.prototype.setIrreplaceable = function (irreplaceable = false) { - this.isStatic = irreplaceable; - this.canBeEmpty = !irreplaceable; - this.fixLayout(); -}; - -MultiArgMorph.prototype.setInfix = function (separator = '') { - var inps; - if (this.infix === separator) { - return; - } - inps = this.inputs(); - this.collapseAll(); - this.infix = separator; - inps.forEach(slot => this.replaceInput(this.addInput(), slot)); - if (inps.length === 1 && this.infix) { // show at least 2 slots with infix - this.addInput(); - } -}; - -MultiArgMorph.prototype.setCollapse = function (collapse = '') { - var inps, coll, collapseLabel; - if (this.collapse === collapse) { - return; - } - coll = this.collapseLabel(); - inps = this.inputs(); - this.collapseAll(); - this.collapse = collapse; - this.removeChild(coll); // shouldn't matter if coll is null - if (this.collapse) { - collapseLabel = this.labelPart(this.collapse); - this.addChildFirst(collapseLabel); - collapseLabel.hide(); - } - inps.forEach(slot => this.replaceInput(this.addInput(), slot)); - if (inps.length === 1 && this.infix) { // show at least 2 slots with infix - this.addInput(); - } - this.fixLayout(); -}; - -MultiArgMorph.prototype.setExpand = function (expand) { - var inps, label; - - // parse expansion labels to determine its cardiinality - function massage(str) { - var items = (str || '').toString().split('\n').map(line => - line.trim()).filter(each => each.length); - return items.length > 1 ? items : items[0] || null; - } - - if (this.labelText === expand) { - return; - } - label = this.label(); - inps = this.inputs(); - this.collapseAll(); - this.labelText = massage(expand); - this.removeChild(label); // shouldn't matter if coll is null - if (this.labelText) { - label = this.labelPart( - this.labelText instanceof Array ? - this.labelText[0] - : this.labelText - ); - this.children.splice(this.collapse ? 1 : 0, null, label); - label.parent = this; - label.hide(); - } - inps.forEach(slot => this.replaceInput(this.addInput(), slot)); - if (inps.length === 1 && this.infix) { // show at least 2 slots with infix - this.addInput(); - } - this.fixLayout(); -}; - -MultiArgMorph.prototype.setDefaultValue = function (defaultValue) { - - // parse default values to determine their arity - function massage(str) { - var items = (str || '').toString().split('\n') - // .map(line => line.trim()) - .filter(each => each.length); - return items.length > 1 ? items : items[0] || null; - } - - if (this.defaultValue === defaultValue) { - return; - } - this.defaultValue = massage(defaultValue); -}; - -MultiArgMorph.prototype.setInitialSlots = function (initialSlots) { - this.initialSlots = Math.min(initialSlots, 12); -}; - -MultiArgMorph.prototype.setMinSlots = function (minSlots) { - this.minInputs = Math.min(minSlots, 12); -}; - -MultiArgMorph.prototype.setMaxSlots = function (maxSlots) { - this.maxInputs = +maxSlots; -}; - -// MultiArgMorph defaults: - -MultiArgMorph.prototype.setContents = function (anArray) { - var inputs = this.inputs(), i; - - if (!(anArray instanceof Array) && this.slotSpec === '%rcv') { - // special case for migrating former SEND block inputs to - // newer BROADCAST expansion slots for receivers - // this can be removed once all SEND blocks have been - // converted to v7 - anArray = [anArray]; - } - - for (i = 0; i < anArray.length; i += 1) { - if (anArray[i] !== null && (inputs[i])) { - inputs[i].setContents(anArray[i]); - } - } -}; - -// MultiArgMorph hiding and showing: - -/* - override the inherited behavior to recursively hide/show all - children, so that my instances get restored correctly when - switching back out of app mode. -*/ - -MultiArgMorph.prototype.hide = function () { - this.isVisible = false; - this.changed(); -}; - -MultiArgMorph.prototype.show = function () { - this.isVisible = true; - this.changed(); -}; - -// MultiArgMorph coloring: - -MultiArgMorph.prototype.setLabelColor = function ( - textColor, - shadowColor, - shadowOffset -) { - this.textColor = textColor; - this.shadowColor = shadowColor; - this.shadowOffset = shadowOffset; - MultiArgMorph.uber.setLabelColor.call( - this, - textColor, - shadowColor, - shadowOffset - ); -}; - -// MultiArgMorph layout: - -MultiArgMorph.prototype.fixLayout = function () { - var labels, shadowColor, shadowOffset, block; - if (this.slotSpec === '%t') { - this.isStatic = true; // in this case I cannot be exchanged - } - if (this.parent) { - labels = this.allLabels(); - this.color = this.parent.color; - this.arrows().color = this.color; - shadowColor = this.shadowColor || - this.parent.color.darker(this.labelContrast); - block = this.parentThatIsA(BlockMorph); - this.arrows().children[2].shadowColor = block ? - block.color.darker(this.labelContrast) - : shadowColor; - if (labels.length) { - labels.forEach(label => { - shadowOffset = this.shadowOffset || - (label ? label.shadowOffset : null); - if (!label.shadowColor.eq(shadowColor)) { - label.shadowColor = shadowColor; - label.shadowOffset = shadowOffset; - label.fixLayout(); - label.rerender(); - } - }); - } - } - this.fixArrowsLayout(); - MultiArgMorph.uber.fixLayout.call(this); - if (this.parent) { - this.parent.fixLayout(); - } -}; - -MultiArgMorph.prototype.fixArrowsLayout = function () { - var label = this.label(), - collapseLabel = this.collapseLabel(), - arrows = this.arrows(), - leftArrow = arrows.children[0], - rightArrow = arrows.children[1], - listSymbol = arrows.children[2], - inpCount = this.inputs().length, - dim = new Point(rightArrow.width() / 2, rightArrow.height()), - centerList = true; - leftArrow.show(); - listSymbol.show(); - rightArrow.show(); - arrows.setHeight(dim.y); - if (collapseLabel) { - collapseLabel.hide(); - } - if (this.isStatic) { - listSymbol.hide(); - } - if (inpCount < (this.minInputs + 1)) { // hide left arrow - if (label) { - label.hide(); - } - leftArrow.hide(); - if (this.isStatic) { - arrows.setWidth(dim.x); - } else { - if (collapseLabel) { - collapseLabel.show(); - } - arrows.setWidth(dim.x * 1.3 + listSymbol.width()); - listSymbol.setCenter(arrows.center()); - listSymbol.setLeft(arrows.left()); - centerList = false; - } - } else if (this.is3ArgRingInHOF() && inpCount > 2) { // hide right arrow - rightArrow.hide(); - arrows.width(dim.x); - } else { // show both arrows - if (label) { - label.show(); - } - arrows.setWidth(dim.x * 2.4 + (this.isStatic ? 0 : listSymbol.width())); - if (this.maxInputs && inpCount > this.maxInputs - 1) { - // hide right arrow - rightArrow.hide(); - arrows.setWidth(dim.x); - } - } - leftArrow.setCenter(arrows.center()); - leftArrow.setLeft(arrows.left()); - rightArrow.setCenter(arrows.center()); - rightArrow.setRight(arrows.right()); - if (centerList) { - listSymbol.setCenter(arrows.center()); - } - arrows.rerender(); -}; - -MultiArgMorph.prototype.fixHolesLayout = function () { - var pos; - this.holes = []; - if (this.slotSpec.includes('%cs')) { - pos = this.position(); - this.inputs().forEach(slot => { - if (slot instanceof CSlotMorph) { - slot.fixHolesLayout(); - this.holes.push( - slot.holes[0].translateBy(slot.position().subtract(pos)) - ); - } - }); - } -}; - -MultiArgMorph.prototype.refresh = function () { - this.inputs().forEach(input => { - input.fixLayout(); - input.rerender(); - }); -}; - -// MultiArgMorph deleting & inserting slots: -/* - caution, only call these methods with "primitive" inputs, - since they don't preserve embedded blocks (yes, on purpose) -*/ - -MultiArgMorph.prototype.deleteSlot = function (anInput) { - var len = this.inputs().length, - idx = this.children.indexOf(anInput), - block = this.parentThatIsA(BlockMorph), - sprite = block.scriptTarget(); - if (len <= this.minInputs) { - return; - } - if (this.infix) { - if (idx === (this.children.length - 2)) { // b/c arrows - this.removeChild(this.children[idx - 1]); - } else { - this.removeChild(this.children[idx + 1]); - } - } - this.removeChild(anInput); - this.fixLayout(); - sprite.recordUserEdit( - 'scripts', - 'poly slot', - 'delete', - block.abstractBlockSpec() - ); -}; - -MultiArgMorph.prototype.insertNewInputBefore = function (anInput, contents) { - var idx = this.children.indexOf(anInput), - newPart = this.labelPart(this.slotSpec), - block = this.parentThatIsA(BlockMorph), - sprite = block.scriptTarget(), - infix; - - if (this.maxInputs && (this.inputs().length >= this.maxInputs)) { - return; - } - if (contents) { - newPart.setContents(contents); - } - newPart.parent = this; - if (this.infix) { - infix = this.labelPart(localize(this.infix)); - infix.parent = this; - this.children.splice(idx, 0, newPart, infix); - } else { - this.children.splice(idx, 0, newPart); - } - newPart.fixLayout(); - if (this.parent instanceof BlockMorph) { - this.parent.fixLabelColor(); - } - this.fixLayout(); - sprite.recordUserEdit( - 'scripts', - 'poly slot', - 'insert', - block.abstractBlockSpec() - ); - return newPart; -}; - -// MultiArgMorph arity control: - -MultiArgMorph.prototype.addInput = function (contents) { - var len = this.inputs().length, - newPart = this.labelPart(this.slotSpecFor(len)), - value = isNil(contents) ? this.defaultValueFor(len) : contents, - i, name, idx; - - this.addInfix(); - idx = this.children.length - 1; - if (value !== '' && !isNil(value)) { - newPart.setContents(value); - } else if (this.elementSpec === '%scriptVars' || - this.elementSpec === '%blockVars') { - name = ''; - i = idx; - if (this.elementSpec === '%scriptVars') { - // compensate for missing label element - i += 1; - } - while (i > 0) { - name = String.fromCharCode(97 + (i - 1) % 26) + name; - i = Math.floor((i - 1) / 26); - } - newPart.setContents(name); - } else if (contains(['%parms', '%ringparms'], this.elementSpec)) { - if (this.is3ArgRingInHOF() && idx < 5) { - newPart.setContents([ - localize('value'), - localize('index'), - localize('list') - ][idx - 1]); - } else { - newPart.setContents('#' + idx); - } - } else if (this.elementSpec === '%message') { - newPart.setContents(localize('data')); - } else if (this.elementSpec === '%keyName') { - newPart.setContents(localize('key')); - } - newPart.parent = this; - this.children.splice(idx, 0, newPart); - this.addPostfix(); - newPart.fixLayout(); - if (this.parent instanceof BlockMorph) { - this.parent.fixLabelColor(); - } - this.fixLayout(); - return newPart; -}; - -MultiArgMorph.prototype.addInfix = function () { - var infix, - len = this.inputs().length, - label = this.infix ? localize(this.infix) - : (this.labelText instanceof Array ? - (this.slotSpec instanceof Array ? - this.labelText[len % this.slotSpec.length] - : this.labelText[len % this.labelText.length]) - : ''); - - if (label === '' || !len || this.children.length < 2) {return; } - infix = this.labelPart(label); - infix.parent = this; - this.children.splice(this.children.length - 1, 0, infix); -}; - -MultiArgMorph.prototype.addPostfix = function () { - var postfix; - if (this.labelText instanceof Array && - this.slotSpec instanceof Array && - this.inputs().length % this.slotSpec.length === 0 && - this.labelText.length === (this.slotSpec.length + 1) - ) { - postfix = this.labelPart(this.labelText[this.slotSpec.length]); - postfix.parent = this; - this.children.splice(this.children.length - 1, 0, postfix); - } -}; - -MultiArgMorph.prototype.removePostfix = function (idx) { - if (this.labelText instanceof Array && - idx % this.slotSpec.length === 0 && - this.labelText.length === (this.slotSpec.length + 1) - ) { - this.removeChild(this.children[this.children.length - 2]); - } -}; - -MultiArgMorph.prototype.removeInput = function () { - var len = this.inputs().length, - oldPart, scripts; - if (len > 0) { - this.removePostfix(len); - oldPart = this.inputs()[len - 1]; - this.removeChild(oldPart); - if (oldPart instanceof CSlotMorph) { - oldPart = oldPart.nestedBlock(); - } - if (oldPart instanceof BlockMorph && - !(oldPart instanceof RingMorph && !oldPart.contents())) { - scripts = this.parentThatIsA(ScriptsMorph); - if (scripts) { - oldPart.moveBy(10); - scripts.add(oldPart); - } - } - } - if (this.infix || - (this.labelText instanceof Array && this.inputs().length) - ) { - if (this.children.length > (this.collapse ? 2 : 1) && - !(this.labelText instanceof Array && - this.labelText[this.inputs().length % this.slotSpec.length] - === '') - ) { - this.removeChild(this.children[this.children.length - 2]); - } - } - this.fixLayout(); -}; - -MultiArgMorph.prototype.collapseAll = function () { - var len = this.inputs().length, - i; - for (i = 0; i < len; i+= 1) { - this.removeInput(); - } -}; - -MultiArgMorph.prototype.isVertical = function () { - return contains(['%repRing', '%predRing', '%cmdRing'], this.slotSpec); -}; - -MultiArgMorph.prototype.is3ArgRingInHOF = function () { - // answer true if I am embedded into a ring inside a HOF block - // that supports 3 parameters ("item, idx, data") - // of which there are currently only MAP, KEEP and FIND - // and their atomic counterparts - var ring = this.parent, - block; - if (ring) { - block = ring.parent; - if (block instanceof ReporterBlockMorph) { - return block.inputs()[0] === ring && - contains( - [ - 'reportMap', - 'reportAtomicMap', - 'reportKeep', - 'reportAtomicKeep', - 'reportFindFirst', - 'reportAtomicFindFirst' - ], - block.selector - ); - } - } - return false; -}; - -MultiArgMorph.prototype.slotSpecFor = function (index) { - return this.slotSpec instanceof Array ? - this.slotSpec[index % this.slotSpec.length] - : this.slotSpec; -}; - -MultiArgMorph.prototype.defaultValueFor = function (index) { - var dta = this.defaultValueDataFor(index); - return this.parentThatIsA(BlockMorph)?.definition?.selector ? - localize(dta) : dta; -}; - -MultiArgMorph.prototype.defaultValueDataFor = function (index) { - // private - answer the raw untranslated data - // repeat & wrap default values inside label groups - if (!this.parent || this.groupInputs > 1) { - return this.defaultValue instanceof Array ? - this.defaultValue[index % this.defaultValue.length] - : this.defaultValue; - } - - // otherwise use them just once each - if (this.defaultValue instanceof Array) { - return this.defaultValue[index] || ''; - } - return index ? '' : this.defaultValue; -}; - -// MultiArgMorph events: - -MultiArgMorph.prototype.mouseClickLeft = function (pos) { - // prevent expansion in the palette - // (because it can be hard or impossible to collapse again) - var block = this.parentThatIsA(BlockMorph), - sprite = block.scriptTarget(); - if (!this.parentThatIsA(ScriptsMorph)) { - this.escalateEvent('mouseClickLeft', pos); - return; - } - // if the key is pressed, repeat action 3 times - var target = this.selectForEdit(), - arrows = target.arrows(), - leftArrow = arrows.children[0], - rightArrow = arrows.children[1], - arrowsBounds = target.arrows().bounds.expandBy(this.fontSize / 3), - arrowsCenter = arrows.center().x, - isExpansionClick, - repetition = this.groupInputs * - (target.world().currentKey === 16 ? 3 : 1), - i; - - if (arrowsBounds.containsPoint(pos)) { - if (leftArrow.isVisible && rightArrow.isVisible) { - isExpansionClick = pos.x >= arrowsCenter; - } else { - isExpansionClick = rightArrow.isVisible; - } - if (isExpansionClick) { // right arrow - if (this.infix && !this.inputs().length) { - repetition = Math.max(repetition, 2); - } - for (i = 0; i < repetition; i += 1) { - if (rightArrow.isVisible) { - target.addInput(); - } - } - sprite.recordUserEdit( - 'scripts', - 'poly slot', - 'expand', - block.abstractBlockSpec() - ); - } else { // left arrow - if (this.infix && this.inputs().length < 3) { - repetition = 2; - } - for (i = 0; i < repetition; i += 1) { - if (leftArrow.isVisible) { - target.removeInput(); - } - } - sprite.recordUserEdit( - 'scripts', - 'poly slot', - 'collapse', - block.abstractBlockSpec() - ); - } - } else { - target.escalateEvent('mouseClickLeft', pos); - } -}; - -// MultiArgMorph menu: - -MultiArgMorph.prototype.userMenu = function () { - var menu = new MenuMorph(this), - block = this.parentThatIsA(BlockMorph), - key = ''; - if (!StageMorph.prototype.enableCodeMapping) { - return this.parent.userMenu(); - } - if (block) { - if (block instanceof RingMorph) { - key = 'parms_'; - } else if (block.selector === 'doDeclareVariables') { - key = 'tempvars_'; - } - } - menu.addItem( - 'code list mapping...', - () => this.mapCodeList(key) - ); - menu.addItem( - 'code item mapping...', - () => this.mapCodeItem(key) - ); - menu.addItem( - 'code delimiter mapping...', - () => this.mapCodeDelimiter(key) - ); - return menu; -}; - -// MultiArgMorph code mapping - -/* - code mapping lets you use blocks to generate arbitrary text-based - source code that can be exported and compiled / embedded elsewhere, - it's not part of Snap's evaluator and not needed for Snap itself -*/ - -MultiArgMorph.prototype.mapCodeDelimiter = function (key) { - this.mapToCode(key + 'delim', 'list item delimiter'); -}; - -MultiArgMorph.prototype.mapCodeList = function (key) { - this.mapToCode(key + 'list', 'list contents <#1>'); -}; - -MultiArgMorph.prototype.mapCodeItem = function (key) { - this.mapToCode(key + 'item', 'list item <#1>'); -}; - -MultiArgMorph.prototype.mapToCode = function (key, label) { - // private - open a dialog box letting the user map code via the GUI - new DialogBoxMorph( - this, - code => StageMorph.prototype.codeMappings[key] = code, - this - ).promptCode( - 'Code mapping - ' + label, - StageMorph.prototype.codeMappings[key] || '', - this.world() - ); -}; - -MultiArgMorph.prototype.mappedCode = function (definitions) { - var block = this.parentThatIsA(BlockMorph), - key = '', - code, - items = '', - itemCode, - delim, - count = 0, - parts = []; - - if (block) { - if (block instanceof RingMorph) { - key = 'parms_'; - } else if (block.selector === 'doDeclareVariables') { - key = 'tempvars_'; - } - } - - code = StageMorph.prototype.codeMappings[key + 'list'] || '<#1>'; - itemCode = StageMorph.prototype.codeMappings[key + 'item'] || '<#1>'; - delim = StageMorph.prototype.codeMappings[key + 'delim'] || ' '; - - this.inputs().forEach(input => - parts.push(itemCode.replace(/<#1>/g, input.mappedCode(definitions))) - ); - parts.forEach(part => { - if (count) { - items += delim; - } - items += part; - count += 1; - }); - code = code.replace(/<#1>/g, items); - return code; -}; - -// MultiArgMorph arity evaluating: - -MultiArgMorph.prototype.evaluate = function () { - // this is usually overridden by the interpreter. This method is only - // called (and needed) for the variables menu. - - var result = []; - this.inputs().forEach(slot => - result.push(slot.evaluate()) - ); - return result; -}; - -MultiArgMorph.prototype.isEmptySlot = function () { - return this.canBeEmpty ? this.inputs().length === 0 : false; -}; - -// MultiArgMorph op-sequence analysis - -MultiArgMorph.prototype.unwind = BlockMorph.prototype.unwind; -MultiArgMorph.prototype.unwindAfter = BlockMorph.prototype.unwindAfter; - -// ArgLabelMorph /////////////////////////////////////////////////////// - -/* - I am a label string that is wrapped around an ArgMorph, usually - a MultiArgMorph, so to indicate that it has been replaced entirely - for an embedded reporter block - - I don't have a block spec, I get embedded automatically by the parent - block's argument replacement mechanism - - My evaluation method is the identity function, i.e. I simply pass my - input's value along. -*/ - -// ArgLabelMorph inherits from ArgMorph: - -ArgLabelMorph.prototype = new ArgMorph(); -ArgLabelMorph.prototype.constructor = ArgLabelMorph; -ArgLabelMorph.uber = ArgMorph.prototype; - -// MultiArgMorph instance creation: - -function ArgLabelMorph(argMorph, labelTxt) { - this.init(argMorph, labelTxt); -} - -ArgLabelMorph.prototype.init = function (argMorph, labelTxt) { - var label; - - this.labelText = localize(labelTxt || 'input list:'); - ArgLabelMorph.uber.init.call(this); - - this.isStatic = true; // I cannot be exchanged - - // ArgLabelMorphs are transparent - this.alpha = 0; - - // label text: - label = this.labelPart(this.labelText); - this.add(label); - - // argMorph - this.add(argMorph); -}; - -ArgLabelMorph.prototype.label = function () { - return this.children[0]; -}; - -ArgLabelMorph.prototype.argMorph = function () { - return this.children[1]; -}; - -// ArgLabelMorph layout: - -ArgLabelMorph.prototype.fixLayout = function () { - var label = this.label(), - shadowColor, - shadowOffset; - - if (this.parent) { - this.color = this.parent.color; - shadowOffset = label.shadowOffset || ZERO; - - // determine the shadow color for zebra coloring: - if (shadowOffset.x < 0) { - shadowColor = this.parent.color.darker(this.labelContrast); - } else { - shadowColor = this.parent.color.lighter(this.labelContrast); - } - - if (this.labelText !== '') { - if (!label.shadowColor.eq(shadowColor)) { - label.shadowColor = shadowColor; - label.shadowOffset = shadowOffset; - label.rerender(); - } - } - } - ArgLabelMorph.uber.fixLayout.call(this); - if (this.parent) { - this.parent.fixLayout(); - } -}; - -ArgLabelMorph.prototype.refresh = function () { - this.inputs().forEach(input => { - input.fixLayout(); - input.rerender(); - }); -}; - -// ArgLabelMorph label color: - -ArgLabelMorph.prototype.setLabelColor = function ( - textColor, - shadowColor, - shadowOffset -) { - if (this.labelText !== '') { - var label = this.label(); - label.color = textColor; - label.shadowColor = shadowColor; - label.shadowOffset = shadowOffset; - label.rerender(); - } -}; - -// ArgLabelMorph events: - -ArgLabelMorph.prototype.reactToGrabOf = function () { - if (this.parent instanceof SyntaxElementMorph) { - this.parent.revertToDefaultInput(this); - } -}; - -// ArgLabelMorph evaluating: - -ArgLabelMorph.prototype.evaluate = function () { - // this is usually overridden by the interpreter. This method is only - // called (and needed) for the variables menu. - - return this.argMorph().evaluate(); -}; - -ArgLabelMorph.prototype.isEmptySlot = function () { - return false; -}; - -// FunctionSlotMorph /////////////////////////////////////////////////// - -/* - I am an unevaluated, non-editable, rf-colored, rounded or diamond - input slot. My current (only) use is in the THE BLOCK block. - - My command spec is %f -*/ - -// FunctionSlotMorph inherits from ArgMorph: - -FunctionSlotMorph.prototype = new ArgMorph(); -FunctionSlotMorph.prototype.constructor = FunctionSlotMorph; -FunctionSlotMorph.uber = ArgMorph.prototype; - -// FunctionSlotMorph instance creation: - -function FunctionSlotMorph(isPredicate) { - this.init(isPredicate); -} - -FunctionSlotMorph.prototype.init = function (isPredicate) { - FunctionSlotMorph.uber.init.call(this); - this.isPredicate = isPredicate || false; - this.color = this.rfColor; -}; - -FunctionSlotMorph.prototype.getSpec = function () { - return '%f'; -}; - -// FunctionSlotMorph drawing: - -FunctionSlotMorph.prototype.render = function (ctx) { - var borderColor; - - if (this.parent) { - borderColor = this.parent.color; - } else { - borderColor = new Color(120, 120, 120); - } - - // cache my border colors - this.cachedClr = borderColor.toString(); - this.cachedClrBright = borderColor.lighter(this.contrast) - .toString(); - this.cachedClrDark = borderColor.darker(this.contrast).toString(); - - if (this.isPredicate) { - this.drawDiamond(ctx); - } else { - this.drawRounded(ctx); - } -}; - -FunctionSlotMorph.prototype.drawRounded = function (ctx) { - var h = this.height(), - r = Math.min(this.rounding, h / 2), - w = this.width(), - shift = this.edge / 2, - gradient; - - // draw the 'flat' shape: - ctx.fillStyle = this.color.toString(); - ctx.beginPath(); - - // top left: - ctx.arc( - r, - r, - r, - radians(-180), - radians(-90), - false - ); - - // top right: - ctx.arc( - w - r, - r, - r, - radians(-90), - radians(-0), - false - ); - - // bottom right: - ctx.arc( - w - r, - h - r, - r, - radians(0), - radians(90), - false - ); - - // bottom left: - ctx.arc( - r, - h - r, - r, - radians(90), - radians(180), - false - ); - - ctx.closePath(); - ctx.fill(); - - if (MorphicPreferences.isFlat) {return; } - - // add 3D-Effect: - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - // bottom left corner - ctx.strokeStyle = this.cachedClr; //gradient; - ctx.beginPath(); - ctx.arc( - r, - h - r, - r - shift, - radians(90), - radians(180), - false - ); - ctx.stroke(); - - // top right corner - ctx.strokeStyle = this.cachedClr; //gradient; - ctx.beginPath(); - ctx.arc( - w - r, - r, - r - shift, - radians(-90), - radians(0), - false - ); - ctx.stroke(); - - // normal gradient edges - - if (useBlurredShadows) { - ctx.shadowOffsetX = shift; - ctx.shadowOffsetY = shift; - ctx.shadowBlur = this.edge; - ctx.shadowColor = this.color.darker(80).toString(); - } - - // top edge: straight line - gradient = ctx.createLinearGradient( - 0, - 0, - 0, - this.edge - ); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r - shift, shift); - ctx.lineTo(w - r + shift, shift); - ctx.stroke(); - - // top edge: left corner - gradient = ctx.createRadialGradient( - r, - r, - r - this.edge, - r, - r, - r - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrDark); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - r, - r, - r - shift, - radians(180), - radians(270), - false - ); - ctx.stroke(); - - // left edge: straight vertical line - gradient = ctx.createLinearGradient(0, 0, this.edge, 0); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(shift, r); - ctx.lineTo(shift, h - r); - ctx.stroke(); - - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 0; - ctx.shadowBlur = 0; - - // bottom edge: right corner - gradient = ctx.createRadialGradient( - w - r, - h - r, - r - this.edge, - w - r, - h - r, - r - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - w - r, - h - r, - r - shift, - radians(0), - radians(90), - false - ); - ctx.stroke(); - - // bottom edge: straight line - gradient = ctx.createLinearGradient( - 0, - h - this.edge, - 0, - h - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r - shift, h - shift); - ctx.lineTo(w - r + shift, h - shift); - ctx.stroke(); - - // right edge: straight vertical line - gradient = ctx.createLinearGradient(w - this.edge, 0, w, 0); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(w - shift, r + shift); - ctx.lineTo(w - shift, h - r); - ctx.stroke(); - -}; - -FunctionSlotMorph.prototype.drawDiamond = function (ctx) { - var w = this.width(), - h = this.height(), - h2 = Math.floor(h / 2), - r = Math.min(this.rounding, h2), - shift = this.edge / 2, - gradient; - - // draw the 'flat' shape: - ctx.fillStyle = this.color.toString(); - ctx.beginPath(); - - ctx.moveTo(0, h2); - ctx.lineTo(r, 0); - ctx.lineTo(w - r, 0); - ctx.lineTo(w, h2); - ctx.lineTo(w - r, h); - ctx.lineTo(r, h); - - ctx.closePath(); - ctx.fill(); - - if (MorphicPreferences.isFlat) {return; } - - // add 3D-Effect: - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - // half-tone edges - // bottom left corner - ctx.strokeStyle = this.cachedClr; - ctx.beginPath(); - ctx.moveTo(shift, h2); - ctx.lineTo(r, h - shift); - ctx.stroke(); - - // top right corner - ctx.strokeStyle = this.cachedClr; - ctx.beginPath(); - ctx.moveTo(w - shift, h2); - ctx.lineTo(w - r, shift); - ctx.stroke(); - - // normal gradient edges - // top edge: left corner - - if (useBlurredShadows) { - ctx.shadowOffsetX = shift; - ctx.shadowOffsetY = shift; - ctx.shadowBlur = this.edge; - ctx.shadowColor = this.color.darker(80).toString(); - } - - gradient = ctx.createLinearGradient( - 0, - 0, - r, - 0 - ); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(shift, h2); - ctx.lineTo(r, shift); - ctx.stroke(); - - // top edge: straight line - gradient = ctx.createLinearGradient( - 0, - 0, - 0, - this.edge - ); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r, shift); - ctx.lineTo(w - r, shift); - ctx.stroke(); - - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 0; - ctx.shadowBlur = 0; - - // bottom edge: right corner - gradient = ctx.createLinearGradient( - w - r, - 0, - w, - 0 - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(w - r, h - shift); - ctx.lineTo(w - shift, h2); - ctx.stroke(); - - // bottom edge: straight line - gradient = ctx.createLinearGradient( - 0, - h - this.edge, - 0, - h - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r + shift, h - shift); - ctx.lineTo(w - r - shift, h - shift); - ctx.stroke(); -}; - -// ReporterSlotMorph /////////////////////////////////////////////////// - -/* - I am a ReporterBlock-shaped input slot. I can nest as well as - accept reporter blocks (containing reified scripts). - - my most important accessor is - - nestedBlock() - answer the reporter block I encompass, if any - - My command spec is %r for reporters (round) and %p for - predicates (diamond) - - evaluate() returns my nested block or null -*/ - -// ReporterSlotMorph inherits from FunctionSlotMorph: - -ReporterSlotMorph.prototype = new FunctionSlotMorph(); -ReporterSlotMorph.prototype.constructor = ReporterSlotMorph; -ReporterSlotMorph.uber = FunctionSlotMorph.prototype; - -// ReporterSlotMorph instance creation: - -function ReporterSlotMorph(isPredicate) { - this.init(isPredicate); -} - -ReporterSlotMorph.prototype.init = function (isPredicate) { - ReporterSlotMorph.uber.init.call(this, isPredicate, true); - this.add(this.emptySlot()); - this.fixLayout(); -}; - -ReporterSlotMorph.prototype.emptySlot = function () { - var empty = new ArgMorph(), - shrink = this.rfBorder * 2 + this.edge * 2; - empty.color = this.rfColor; - empty.alpha = 0; - empty.bounds.setExtent(new Point( - (this.fontSize + this.edge * 2) * 2 - shrink, - this.fontSize + this.edge * 2 - shrink - )); - return empty; -}; - -// ReporterSlotMorph accessing: - -ReporterSlotMorph.prototype.getSpec = function () { - return '%r'; -}; - -ReporterSlotMorph.prototype.contents = function () { - return this.children[0]; -}; - -ReporterSlotMorph.prototype.nestedBlock = function () { - var contents = this.contents(); - return contents instanceof ReporterBlockMorph ? contents : null; -}; - -// ReporterSlotMorph evaluating: - -ReporterSlotMorph.prototype.evaluate = function () { - return this.nestedBlock(); -}; - -ReporterSlotMorph.prototype.isEmptySlot = function () { - return this.nestedBlock() === null; -}; - -// ReporterSlotMorph layout: - -ReporterSlotMorph.prototype.fixLayout = function () { - var contents = this.contents(); - if (!contents) { - contents = this.emptySlot(); - this.add(contents); - } - this.bounds.setExtent(contents.extent().add( - this.edge * 2 + this.rfBorder * 2 - )); - contents.setCenter(this.center()); - if (this.parent) { - if (this.parent.fixLayout) { - this.parent.fixLayout(); - } - } -}; - -// RingReporterSlotMorph /////////////////////////////////////////////////// - -/* - I am a ReporterBlock-shaped input slot for use in RingMorphs. - I can nest reporter blocks (both round and diamond) as well - as command blocks (jigsaw shaped). - - My command spec is %rr for reporters (round) and %rp for - predicates (diamond) - - evaluate() returns my nested block or null - (inherited from ReporterSlotMorph -*/ - -// ReporterSlotMorph inherits from FunctionSlotMorph: - -RingReporterSlotMorph.prototype = new ReporterSlotMorph(); -RingReporterSlotMorph.prototype.constructor = RingReporterSlotMorph; -RingReporterSlotMorph.uber = ReporterSlotMorph.prototype; - -// ReporterSlotMorph preferences settings: - -RingReporterSlotMorph.prototype.rfBorder - = RingCommandSlotMorph.prototype.rfBorder; - -RingReporterSlotMorph.prototype.edge - = RingCommandSlotMorph.prototype.edge; - -RingReporterSlotMorph.prototype.enableCommandDrops = true; - -// RingReporterSlotMorph instance creation: - -function RingReporterSlotMorph(isPredicate) { - this.init(isPredicate); -} - -RingReporterSlotMorph.prototype.init = function (isPredicate) { - RingReporterSlotMorph.uber.init.call(this, isPredicate, true); - this.contrast = RingMorph.prototype.contrast; -}; - -// RingReporterSlotMorph accessing: - -RingReporterSlotMorph.prototype.getSpec = function () { - return '%rr'; -}; - -RingReporterSlotMorph.prototype.replaceInput = function ( - source, - target, - noVanish -) { - RingReporterSlotMorph.uber.replaceInput.call(this, source, target); - if (this.parent instanceof RingMorph && !noVanish) { - this.parent.vanishForSimilar(); - } -}; - -// RingReporterSlotMorph attach targets for commands: - -RingReporterSlotMorph.prototype.slotAttachPoint = - CommandSlotMorph.prototype.slotAttachPoint; - -RingReporterSlotMorph.prototype.dentLeft = - CommandSlotMorph.prototype.dentLeft; - -RingReporterSlotMorph.prototype.dentCenter = - CommandSlotMorph.prototype.dentCenter; - -RingReporterSlotMorph.prototype.attachTargets = function () { - if (!RingReporterSlotMorph.prototype.enableCommandDrops || - this.contents() instanceof ReporterBlockMorph - ) { - // don't let commands "kick out" embedded reporters - return []; - } - return CommandSlotMorph.prototype.attachTargets.call(this); -}; - -// RingReporterSlotMorph nesting for commands: - -RingReporterSlotMorph.prototype.nestedBlock = function (block) { - if (block) { - var nb = this.nestedBlock(); - this.replaceInput(this.children[0], block); - if (nb) { - block.bottomBlock().nextBlock(nb); - } - this.fixLayout(); - } else { - return detect( - this.children, - child => child instanceof BlockMorph - ); - } -}; - -// RingReporterSlotMorph layout: - -RingReporterSlotMorph.prototype.fixLayout = function () { - if (this.contents() instanceof CommandBlockMorph) { - CommandSlotMorph.prototype.fixLayout.call(this); - } else { - RingReporterSlotMorph.uber.fixLayout.call(this); - } -}; - -// RingReporterSlotMorph drawing: - -RingReporterSlotMorph.prototype.render = function (ctx) { - if (MorphicPreferences.isFlat) {return; } - - // init - this.cachedClr = this.color.toString(); - this.cachedClrBright = this.bright(); - this.cachedClrDark = this.dark(); - ctx.fillStyle = this.cachedClr; - - // only add 3D-Effect here, rendering of the flat shape happens at the - // encompassing block level - if (this.isPredicate) { - this.drawEdgesDiamond(ctx); - } else { - this.drawEdgesOval(ctx); - } -}; - -RingReporterSlotMorph.prototype.outlinePath = function (ctx, offset) { - if (this.isPredicate) { - this.outlinePathDiamond(ctx, offset); - } else { - this.outlinePathOval(ctx, offset); - } -}; - -RingReporterSlotMorph.prototype.outlinePathOval = function (ctx, offset) { - var ox = offset.x, - oy = offset.y, - w = this.width(), - h = this.height(), - r = Math.min(this.rounding, h / 2); - - // top left: - ctx.arc( - r + this.edge + ox, - r + this.edge + oy, - r, - radians(-180), - radians(-90), - false - ); - - // top right: - ctx.arc( - w - r - this.edge + ox, - r + this.edge + oy, - r, - radians(-90), - radians(-0), - false - ); - - // bottom right: - ctx.arc( - w - r - this.edge + ox, - h - r - this.edge + oy, - r, - radians(0), - radians(90), - false - ); - - // bottom left: - ctx.arc( - r + this.edge + ox, - h - r - this.edge + oy, - r, - radians(90), - radians(180), - false - ); - - // "close" the path - ctx.lineTo(this.edge + ox, r + this.edge + oy); -}; - -RingReporterSlotMorph.prototype.drawEdgesOval = function (ctx) { - var h = this.height(), - r = Math.min(this.rounding, h / 2), - w = this.width(), - shift = this.edge / 2, - gradient; - - - // add 3D-Effect: - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - // bottom left corner - ctx.strokeStyle = this.cachedClr; - ctx.beginPath(); - ctx.arc( - r, - h - r, - r - shift, - radians(90), - radians(180), - false - ); - ctx.stroke(); - - // top right corner - ctx.strokeStyle = this.cachedClr; - ctx.beginPath(); - ctx.arc( - w - r, - r, - r - shift, - radians(-90), - radians(0), - false - ); - ctx.stroke(); - - // normal gradient edges - - if (useBlurredShadows) { - ctx.shadowOffsetX = shift; - ctx.shadowOffsetY = shift; - ctx.shadowBlur = this.edge; - ctx.shadowColor = this.color.darker(80).toString(); - } - - // top edge: straight line - gradient = ctx.createLinearGradient( - 0, - 0, - 0, - this.edge - ); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r - shift, shift); - ctx.lineTo(w - r + shift, shift); - ctx.stroke(); - - // top edge: left corner - gradient = ctx.createRadialGradient( - r, - r, - r - this.edge, - r, - r, - r - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrDark); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - r, - r, - r - shift, - radians(180), - radians(270), - false - ); - ctx.stroke(); - - // left edge: straight vertical line - gradient = ctx.createLinearGradient(0, 0, this.edge, 0); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(shift, r); - ctx.lineTo(shift, h - r); - ctx.stroke(); - - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 0; - ctx.shadowBlur = 0; - - // bottom edge: right corner - gradient = ctx.createRadialGradient( - w - r, - h - r, - r - this.edge, - w - r, - h - r, - r - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - w - r, - h - r, - r - shift, - radians(0), - radians(90), - false - ); - ctx.stroke(); - - // bottom edge: straight line - gradient = ctx.createLinearGradient( - 0, - h - this.edge, - 0, - h - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r - shift, h - shift); - ctx.lineTo(w - r + shift, h - shift); - ctx.stroke(); - - // right edge: straight vertical line - gradient = ctx.createLinearGradient(w - this.edge, 0, w, 0); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(w - shift, r + shift); - ctx.lineTo(w - shift, h - r); - ctx.stroke(); -}; - -RingReporterSlotMorph.prototype.outlinePathDiamond = function (ctx, offset) { - var ox = offset.x, - oy = offset.y, - w = this.width(), - h = this.height(), - h2 = Math.floor(h / 2), - r = Math.min(this.rounding, h2); - - ctx.moveTo(ox + this.edge, h2 + oy); - ctx.lineTo(r + this.edge + ox, this.edge + oy); - ctx.lineTo(w - r - this.edge + ox, this.edge + oy); - ctx.lineTo(w - this.edge + ox, h2 + oy); - ctx.lineTo(w - r - this.edge + ox, h - this.edge + oy); - ctx.lineTo(r + this.edge + ox, h - this.edge + oy); - ctx.lineTo(ox + this.edge, h2 + oy); -}; - -RingReporterSlotMorph.prototype.drawEdgesDiamond = function (ctx) { - var w = this.width(), - h = this.height(), - h2 = Math.floor(h / 2), - r = Math.min(this.rounding, h2), - shift = this.edge / 2, - gradient; - - // add 3D-Effect: - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - // half-tone edges - // bottom left corner - ctx.strokeStyle = this.cachedClr; - ctx.beginPath(); - ctx.moveTo(shift, h2); - ctx.lineTo(r, h - shift); - ctx.stroke(); - - // top right corner - ctx.strokeStyle = this.cachedClr; - ctx.beginPath(); - ctx.moveTo(w - shift, h2); - ctx.lineTo(w - r, shift); - ctx.stroke(); - - // normal gradient edges - // top edge: left corner - - if (useBlurredShadows) { - ctx.shadowOffsetX = shift; - ctx.shadowOffsetY = shift; - ctx.shadowBlur = this.edge; - ctx.shadowColor = this.color.darker(80).toString(); - } - - gradient = ctx.createLinearGradient( - 0, - 0, - r, - 0 - ); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(shift, h2); - ctx.lineTo(r, shift); - ctx.stroke(); - - // top edge: straight line - gradient = ctx.createLinearGradient( - 0, - 0, - 0, - this.edge - ); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r, shift); - ctx.lineTo(w - r, shift); - ctx.stroke(); - - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 0; - ctx.shadowBlur = 0; - - // bottom edge: right corner - gradient = ctx.createLinearGradient( - w - r, - 0, - w, - 0 - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(w - r, h - shift); - ctx.lineTo(w - shift, h2); - ctx.stroke(); - - // bottom edge: straight line - gradient = ctx.createLinearGradient( - 0, - h - this.edge, - 0, - h - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r + shift, h - shift); - ctx.lineTo(w - r - shift, h - shift); - ctx.stroke(); -}; - -// CommentMorph ////////////////////////////////////////////////////////// - -/* - I am an editable, multi-line non-scrolling text window. I can be collapsed - to a single abbreviated line or expanded to full. My width can be adjusted - by the user, by height is determined by the size of my text body. I can be - either placed in a scripting area or "stuck" to a block. -*/ - -// CommentMorph inherits from BoxMorph: - -CommentMorph.prototype = new BoxMorph(); -CommentMorph.prototype.constructor = CommentMorph; -CommentMorph.uber = BoxMorph.prototype; - -// CommentMorph preferences settings (pseudo-inherited from SyntaxElement): - -CommentMorph.prototype.refreshScale = function () { - CommentMorph.prototype.fontSize = SyntaxElementMorph.prototype.fontSize; - CommentMorph.prototype.padding = 5 * SyntaxElementMorph.prototype.scale; - CommentMorph.prototype.rounding = 8 * SyntaxElementMorph.prototype.scale; -}; - -CommentMorph.prototype.refreshScale(); - -// CommentMorph instance creation: - -function CommentMorph(contents) { - this.init(contents); -} - -CommentMorph.prototype.init = function (contents) { - var scale = SyntaxElementMorph.prototype.scale; - - this.block = null; // optional anchor block - this.stickyOffset = null; // not to be persisted - this.isCollapsed = false; - this.titleBar = new BoxMorph( - this.rounding, - scale, - new Color(255, 255, 180) - ); - this.titleBar.color = new Color(255, 255, 180); - this.titleBar.setHeight(fontHeight(this.fontSize) + this.padding); - this.title = null; - this.arrow = new ArrowMorph( - 'down', - this.fontSize - ); - this.arrow.mouseClickLeft = () => this.toggleExpand(); - this.contents = new TextMorph( - contents || localize('add comment here...'), - this.fontSize - ); - this.contents.isEditable = true; - this.contents.enableSelecting(); - this.contents.maxWidth = 90 * scale; - this.contents.fixLayout(); - this.handle = new HandleMorph( - this.contents, - 80, - this.fontSize * 2, - -2, - -2 - ); - this.handle.setExtent(new Point(11 * scale, 11 * scale)); - this.anchor = null; - - CommentMorph.uber.init.call( - this, - this.rounding, - scale, - new Color(255, 255, 180) - ); - this.color = new Color(255, 255, 220); - this.isDraggable = true; - this.add(this.titleBar); - this.add(this.arrow); - this.add(this.contents); - this.add(this.handle); - - this.fixLayout(); -}; - -// CommentMorph ops: - -CommentMorph.prototype.fullCopy = function () { - var cpy = new CommentMorph(this.contents.text); - cpy.isCollapsed = this.isCollapsed; - cpy.setTextWidth(this.textWidth()); - if (this.selectionID) { // for copy on write - cpy.selectionID = true; - } - return cpy; -}; - -CommentMorph.prototype.setTextWidth = function (pixels) { - this.contents.maxWidth = pixels; - this.contents.fixLayout(); - this.fixLayout(); -}; - -CommentMorph.prototype.textWidth = function () { - return this.contents.maxWidth; -}; - -CommentMorph.prototype.text = function () { - return this.contents.text; -}; - -CommentMorph.prototype.toggleExpand = function () { - var scripts = this.parentThatIsA(ScriptsMorph); - this.isCollapsed = !this.isCollapsed; - this.fixLayout(); - this.align(); - if (!this.isCollapsed) { - this.comeToFront(); - } - if (scripts) { - scripts.scriptTarget().recordUserEdit( - 'scripts', - 'comment', - this.isCollapsed ? 'collapse' : 'expand' - ); - } -}; - -CommentMorph.prototype.comeToFront = function () { - if (this.parent) { - this.parent.add(this); - this.changed(); - } -}; - -// CommentMorph events: - -CommentMorph.prototype.mouseClickLeft = function () { - this.comeToFront(); -}; - -CommentMorph.prototype.reactToEdit = function () { - var scripts = this.parentThatIsA(ScriptsMorph); - if (scripts) { - scripts.scriptTarget().recordUserEdit( - 'scripts', - 'comment', - 'edit' - ); - } -}; - -// CommentMorph layout: - -CommentMorph.prototype.layoutChanged = function () { - // react to a change of the contents area - this.fixLayout(); - this.align(); - this.comeToFront(); -}; - -CommentMorph.prototype.fixLayout = function () { - var label, - tw = this.contents.width() + 2 * this.padding; - - if (this.title) { - this.title.destroy(); - this.title = null; - } - if (this.isCollapsed) { - this.contents.hide(); - this.title = new FrameMorph(); - this.title.alpha = 0; - this.title.acceptsDrops = false; - label = new StringMorph( - this.contents.text, - this.fontSize, - null, // style (sans-serif) - true // bold - ); - label.rootForGrab = () => this; - this.title.add(label); - this.title.setHeight(label.height()); - this.title.setWidth( - tw - this.arrow.width() - this.padding * 2 - this.rounding - ); - this.add(this.title); - } else { - this.contents.show(); - } - this.titleBar.setWidth(tw); - this.contents.setLeft(this.titleBar.left() + this.padding); - this.contents.setTop(this.titleBar.bottom() + this.padding); - this.arrow.direction = this.isCollapsed ? 'right' : 'down'; - this.arrow.rerender(); - this.arrow.setCenter(this.titleBar.center()); - this.arrow.setLeft(this.titleBar.left() + this.padding); - if (this.title) { - this.title.setPosition( - this.arrow.topRight().add(new Point(this.padding, 0)) - ); - } - this.changed(); - this.bounds.setHeight( - this.titleBar.height() - + (this.isCollapsed ? 0 : - this.padding - + this.contents.height() - + this.padding) - ); - this.bounds.setWidth(this.titleBar.width()); - this.rerender(); - this.handle.fixLayout(); -}; - -// CommentMorph menu: - -CommentMorph.prototype.userMenu = function () { - var menu = new MenuMorph(this); - - menu.addItem( - "duplicate", - () => { - var dup = this.fullCopy(), - ide = this.parentThatIsA(IDE_Morph), - blockEditor = this.parentThatIsA(BlockEditorMorph), - scripts = this.parentThatIsA(ScriptsMorph), - world = this.world(); - dup.pickUp(world); - // register the drop-origin, so the comment can - // slide back to its former situation if dropped - // somewhere where it gets rejected - if (!ide && blockEditor) { - ide = blockEditor.target.parentThatIsA(IDE_Morph); - } - if (ide) { - world.hand.grabOrigin = { - origin: ide.palette, - position: ide.palette.center() - }; - } - if (scripts) { - scripts.scriptTarget().recordUserEdit( - 'scripts', - 'comment', - 'duplicate' - ); - } - }, - 'make a copy\nand pick it up' - ); - menu.addItem("delete", 'userDestroy'); - menu.addItem( - "comment pic...", - () => { - var ide = this.parentThatIsA(IDE_Morph) || - this.parentThatIsA(BlockEditorMorph) - .target.parentThatIsA(IDE_Morph); - ide.saveCanvasAs( - this.fullImage(), - (ide.projectName || localize('untitled')) + ' ' + - localize('comment pic') - ); - }, - 'save a picture\nof this comment' - ); - return menu; -}; - -CommentMorph.prototype.userDestroy = function () { - var scripts = this.parentThatIsA(ScriptsMorph); - if (scripts) { - scripts.scriptTarget().recordUserEdit( - 'scripts', - 'comment', - 'delete' - ); - } - this.selectForEdit().destroy(); // enable copy-on-edit -}; - -// CommentMorph hiding and showing: - -/* - override the inherited behavior to recursively hide/show all - children, so that my instances get restored correctly when - switching back out of app mode. -*/ - -CommentMorph.prototype.hide = function () { - this.isVisible = false; - this.changed(); -}; - -CommentMorph.prototype.show = function () { - this.isVisible = true; - this.changed(); -}; - -// CommentMorph dragging & dropping - -CommentMorph.prototype.prepareToBeGrabbed = function (hand) { - // disassociate from the block I'm posted to - var scripts = this.parentThatIsA(ScriptsMorph); - if (scripts) { - scripts.scriptTarget().recordUserEdit( - 'scripts', - 'comment', - 'grab' - ); - } - if (this.block) { - this.block.comment = null; - this.block = null; - } - if (this.anchor) { - this.anchor.destroy(); - this.anchor = null; - } -}; - -CommentMorph.prototype.justDropped = function (hand) { - var scripts = this.parentThatIsA(ScriptsMorph); - if (scripts) { - scripts.scriptTarget().recordUserEdit( - 'scripts', - 'comment', - 'drop' - ); - } -}; - -CommentMorph.prototype.selectForEdit = - SyntaxElementMorph.prototype.selectForEdit; - -CommentMorph.prototype.snap = function (hand) { - // passing the hand is optional (for when blocks are dragged & dropped) - var scripts = this.parent, - target; - - if (!(scripts instanceof ScriptsMorph)) { - return null; - } - scripts.clearDropInfo(); - target = scripts.closestBlock(this, hand); - if (target !== null) { - target.comment = this; - this.block = target; - if (this.snapSound) { - this.snapSound.play(); - } - scripts.lastDropTarget = {element: target}; - scripts.scriptTarget().recordUserEdit( - 'scripts', - 'comment', - 'snap', - this.block.abstractBlockSpec() - ); - } - this.align(); - scripts.lastDroppedBlock = this; - if (hand) { - scripts.recordDrop(hand.grabOrigin); - } - -}; - -// CommentMorph sticking to blocks - -CommentMorph.prototype.align = function (topBlock, ignoreLayer) { - if (this.block) { - var top = topBlock || this.block.topBlock(), - affectedBlocks, - tp, - bottom, - rightMost, - scripts = top.parentThatIsA(ScriptsMorph); - this.setTop(this.block.top() + this.block.corner); - tp = this.top(); - bottom = this.bottom(); - affectedBlocks = top.allChildren().filter(child => - child instanceof BlockMorph && - child.bottom() > tp && - child.top() < bottom - ); - rightMost = Math.max.apply( - null, - affectedBlocks.map(block => block.right()) - ); - - this.setLeft(rightMost + 5); - if (!ignoreLayer && scripts) { - scripts.addBack(this); // push to back and show - } - - if (!this.anchor) { - this.anchor = new Morph(); - this.anchor.color = this.titleBar.color; - } - this.anchor.setPosition(new Point( - this.block.right(), - this.top() + this.edge - )); - this.anchor.bounds.corner = new Point( - this.left(), - this.top() + this.edge + 1 - ); - this.anchor.rerender(); - this.addBack(this.anchor); - } -}; - -CommentMorph.prototype.startFollowing = function (topBlock, world) { - this.align(topBlock); - world.add(this); - this.addShadow(); - this.stickyOffset = this.position().subtract(this.block.position()); - this.step = () => { - if (!this.block) { // kludge - only needed for "redo" - this.stopFollowing(); - return; - } - this.setPosition(this.block.position().add(this.stickyOffset)); - }; -}; - -CommentMorph.prototype.stopFollowing = function () { - this.removeShadow(); - delete this.step; -}; - -CommentMorph.prototype.destroy = function () { - if (this.block) { - this.block.comment = null; - } - CommentMorph.uber.destroy.call(this); -}; - -CommentMorph.prototype.stackHeight = function () { - return this.height(); -}; - -// ScriptFocusMorph ////////////////////////////////////////////////////////// - -/* - I offer keyboard navigation for syntax elements, blocks and scripts: - - activate: - - shift + click on a scripting pane's background - - shift + click on any block - - shift + enter in the IDE's edit mode - - stop editing: - - left-click on scripting pane's background - - esc - - navigate among scripts: - - tab: next script - - backtab (shift + tab): last script - - start editing a new script: - - shift + enter - - navigate among commands within a script: - - down arrow: next command - - up arrow: last command - - navigate among all elements within a script: - - right arrow: next element (block or input) - - left arrow: last element - - move the currently edited script (stack of blocks): - - shift + arrow keys (left, right, up, down) - - editing scripts: - - - backspace: - * delete currently focused reporter - * delete command above current insertion mark (blinking) - * collapse currently focused variadic input by one element - - - enter: - * edit currently focused input slot - * expand currently focused variadic input by one element - - - space: - * activate currently focused input slot's pull-down menu, if any - * show a menu of reachable variables for the focused input or reporter - - - any other key: - start searching for insertable matching blocks - - - in menus triggered by this feature: - * navigate with up / down arrow keys - * trigger selection with enter - * cancel menu with esc - - - in the search bar triggered b this feature: - * keep typing / deleting to narrow and update matches - * navigate among shown matches with up / down arrow keys - * insert selected match at the focus' position with enter - * cancel searching and inserting with esc - - running the currently edited script: - * shift+ctrl+enter simulates clicking the edited script with the mouse -*/ - -// ScriptFocusMorph inherits from BoxMorph: - -ScriptFocusMorph.prototype = new BoxMorph(); -ScriptFocusMorph.prototype.constructor = ScriptFocusMorph; -ScriptFocusMorph.uber = BoxMorph.prototype; - -// ScriptFocusMorph instance creation: - -function ScriptFocusMorph(editor, initialElement, position) { - this.init(editor, initialElement, position); -} - -ScriptFocusMorph.prototype.init = function ( - editor, - initialElement, - position -) { - this.editor = editor; // a ScriptsMorph - this.element = initialElement; - this.atEnd = false; - ScriptFocusMorph.uber.init.call(this); - if (this.element instanceof ScriptsMorph) { - this.setPosition(position); - } -}; - -// ScriptFocusMorph keyboard focus: - -ScriptFocusMorph.prototype.getFocus = function (world) { - if (!world) {world = this.world(); } - if (world && world.keyboardFocus !== this) { - world.stopEditing(); - } - world.keyboardFocus = this; - this.fixLayout(); - this.editor.updateToolbar(); -}; - -// ScriptFocusMorph layout: - -ScriptFocusMorph.prototype.fixLayout = function () { - this.changed(); - if (this.element instanceof CommandBlockMorph || - this.element instanceof CommandSlotMorph || - this.element instanceof ScriptsMorph) { - this.manifestStatement(); - } else { - this.manifestExpression(); - } - this.editor.add(this); // come to front - this.scrollIntoView(); - this.changed(); -}; - -ScriptFocusMorph.prototype.manifestStatement = function () { - var newScript = this.element instanceof ScriptsMorph, - y = this.element.top(); - this.border = 0; - this.edge = 0; - this.alpha = 1; - this.color = this.editor.feedbackColor; - this.bounds.setExtent(new Point( - newScript ? - SyntaxElementMorph.prototype.hatWidth : this.element.width(), - Math.max( - SyntaxElementMorph.prototype.corner, - SyntaxElementMorph.prototype.feedbackMinHeight - ) - )); - if (this.element instanceof CommandSlotMorph) { - y += SyntaxElementMorph.prototype.corner; - } else if (this.atEnd) { - y = this.element.bottom(); - } - if (!newScript) { - this.setPosition(new Point( - this.element.left(), - y - )); - } - this.fps = 2; - this.show(); - this.step = function () { - this.toggleVisibility(); - }; -}; - -ScriptFocusMorph.prototype.manifestExpression = function () { - this.edge = SyntaxElementMorph.prototype.rounding; - this.border = Math.max( - SyntaxElementMorph.prototype.edge, - 3 - ); - this.color = this.editor.feedbackColor.copy(); - this.color.a = 0.5; - this.borderColor = this.editor.feedbackColor; - - this.bounds = this.element.fullBounds() - .expandBy(Math.max( - SyntaxElementMorph.prototype.edge * 2, - SyntaxElementMorph.prototype.reporterDropFeedbackPadding - )); - this.rerender(); - delete this.fps; - delete this.step; - this.show(); -}; - -// ScriptFocusMorph editing - -ScriptFocusMorph.prototype.trigger = function () { - var current = this.element, - i; - if (current instanceof MultiArgMorph) { - for (i = 0; i < current.groupInputs; i += 1) { - if (current.arrows().children[1].isVisible) { - current.addInput(); - this.fixLayout(); - } - } - return; - } - if (current.parent instanceof TemplateSlotMorph) { - current.mouseClickLeft(); - return; - } - if (current instanceof BooleanSlotMorph) { - current.toggleValue(); - return; - } - if (current instanceof InputSlotMorph) { - if (!current.isReadOnly) { - delete this.fps; - delete this.step; - this.hide(); - this.world().onNextStep = () => { - current.contents().edit(); - current.contents().selectAll(); - }; - } else if (current.choices) { - current.dropDownMenu(true); - delete this.fps; - delete this.step; - this.hide(); - } - } -}; - -ScriptFocusMorph.prototype.menu = function () { - var current = this.element; - if (current instanceof InputSlotMorph && current.choices) { - current.dropDownMenu(true); - delete this.fps; - delete this.step; - this.hide(); - } else { - this.insertVariableGetter(); - } -}; - -ScriptFocusMorph.prototype.deleteLastElement = function () { - var current = this.element, - i; - if (current.parent instanceof ScriptsMorph) { - if (this.atEnd || current instanceof ReporterBlockMorph) { - current.destroy(); - this.element = this.editor; - this.atEnd = false; - } - } else if (current instanceof MultiArgMorph) { - for (i = 0; i < current.groupInputs; i += 1) { - if (current.arrows().children[0].isVisible) { - current.removeInput(); - } - } - } else if (current instanceof BooleanSlotMorph) { - if (!current.isStatic) { - current.setContents(null); - } - } else if (current instanceof ReporterBlockMorph) { - if (!current.isTemplate) { - this.lastElement(); - current.prepareToBeGrabbed(); - current.destroy(); - } - } else if (current instanceof CommandBlockMorph) { - if (this.atEnd) { - this.element = current.parent; - current.userDestroy(); - } else { - if (current.parent instanceof CommandBlockMorph) { - current.parent.userDestroy(); - } - } - } - this.editor.adjustBounds(); - this.fixLayout(); -}; - -ScriptFocusMorph.prototype.insertBlock = function (block) { - // insert the block after a short gliding animation - this.world().add(block); - block.glideTo( - this.position(), - null, - null, - () => this.fillInBlock(block) - ); -}; - -ScriptFocusMorph.prototype.fillInBlock = function (block) { - var pb, stage, ide, rcvr; - block.isTemplate = false; - block.isDraggable = true; - - if (block.snapSound) { - block.snapSound.play(); - } - - if (this.element instanceof ScriptsMorph) { - this.editor.add(block); - this.element = block; - if (block instanceof CommandBlockMorph) { - block.setLeft(this.left()); - if (block.isStop()) { - block.setTop(this.top()); - } else { - block.setBottom(this.top()); - this.atEnd = true; - } - } else { - block.setCenter(this.center()); - block.setLeft(this.left()); - } - } else if (this.element instanceof CommandBlockMorph) { - if (this.atEnd) { - this.element.nextBlock(block); - this.element = block; - this.fixLayout(); - } else { - // to be done: special case if block.isStop() - pb = this.element.parent; - if (pb instanceof ScriptsMorph) { // top block - block.setLeft(this.element.left()); - block.setBottom(this.element.top() + this.element.corner); - this.editor.add(block); - block.nextBlock(this.element); - this.fixLayout(); - } else if (pb instanceof CommandSlotMorph) { - pb.nestedBlock(block); - } else if (pb instanceof RingReporterSlotMorph) { - block.nextBlock(pb.nestedBlock()); - pb.add(block); - pb.fixLayout(); - } else if (pb instanceof CommandBlockMorph) { - pb.nextBlock(block); - } - } - } else if (this.element instanceof CommandSlotMorph) { - // to be done: special case if block.isStop() - this.element.nestedBlock(block); - this.element = block; - this.atEnd = true; - } else { - pb = this.element.parent; - if (pb instanceof ScriptsMorph) { - this.editor.add(block); - block.setPosition(this.element.position()); - this.element.destroy(); - } else { - pb.replaceInput(this.element, block); - } - this.element = block; - } - block.fixBlockColor(); - this.editor.adjustBounds(); - // block.scrollIntoView(); - this.fixLayout(); - - // register generic hat blocks - if (block.selector === 'receiveCondition') { - rcvr = this.editor.scriptTarget(); - if (rcvr) { - stage = rcvr.parentThatIsA(StageMorph); - if (stage) { - stage.enableCustomHatBlocks = true; - stage.threads.pauseCustomHatBlocks = false; - ide = stage.parentThatIsA(IDE_Morph); - if (ide) { - ide.controlBar.stopButton.refresh(); - } - } - } - } - - // experimental: if the inserted block has inputs, go to the first one - if (block.inputs && block.inputs().length) { - this.element = block; - this.atEnd = false; - this.nextElement(); - } -}; - -ScriptFocusMorph.prototype.insertVariableGetter = function () { - var types = this.blockTypes(), - vars, - menu = new MenuMorph(); - if (!types || !contains(types, 'reporter')) { - return; - } - vars = InputSlotMorph.prototype.getVarNamesDict.call(this.element); - Object.keys(vars).forEach(vName => { - var block = SpriteMorph.prototype.variableBlock(vName); - block.addShadow(new Point(3, 3)); - menu.addItem( - block, - () => { - block.removeShadow(); - this.insertBlock(block); - } - ); - }); - if (menu.items.length > 0) { - menu.popup(this.world(), this.element.bottomLeft()); - menu.getFocus(); - } -}; - -ScriptFocusMorph.prototype.stopEditing = function () { - this.editor.focus = null; - this.editor.updateToolbar(); - this.world().keyboardFocus = null; - this.destroy(); -}; - -// ScriptFocusMorph navigation - -ScriptFocusMorph.prototype.lastElement = function () { - var items = this.items(), - idx; - if (!items.length) { - this.shiftScript(new Point(-50, 0)); - return; - } - if (this.atEnd) { - this.element = items[items.length - 1]; - this.atEnd = false; - } else { - idx = items.indexOf(this.element) - 1; - if (idx < 0) {idx = items.length - 1; } - this.element = items[idx]; - } - if (this.element instanceof CommandSlotMorph && - this.element.nestedBlock()) { - this.lastElement(); - } else if (this.element instanceof HatBlockMorph) { - if (items.length > 1) { - this.lastElement(); - } else { - this.atEnd = true; - } - } - this.fixLayout(); -}; - -ScriptFocusMorph.prototype.nextElement = function () { - var items = this.items(), idx, nb; - if (!items.length) { - this.shiftScript(new Point(50, 0)); - return; - } - idx = items.indexOf(this.element) + 1; - if (idx >= items.length) { - idx = 0; - } - this.atEnd = false; - this.element = items[idx]; - if (this.element instanceof CommandSlotMorph) { - nb = this.element.nestedBlock(); - if (nb) {this.element = nb; } - } else if (this.element instanceof HatBlockMorph) { - if (items.length === 1) { - this.atEnd = true; - } else { - this.nextElement(); - } - } - this.fixLayout(); -}; - -ScriptFocusMorph.prototype.lastCommand = function () { - var cm = this.element.parentThatIsA(CommandBlockMorph), - pb; - if (!cm) { - if (this.element instanceof ScriptsMorph) { - this.shiftScript(new Point(0, -50)); - } - return; - } - if (this.element instanceof CommandBlockMorph) { - if (this.atEnd) { - this.atEnd = false; - } else { - pb = cm.parent.parentThatIsA(CommandBlockMorph); - if (pb) { - this.element = pb; - } else { - pb = cm.topBlock().bottomBlock(); - if (pb) { - this.element = pb; - this.atEnd = true; - } - } - } - } else { - this.element = cm; - this.atEnd = false; - } - if (this.element instanceof HatBlockMorph && !this.atEnd) { - this.lastCommand(); - } - this.fixLayout(); -}; - -ScriptFocusMorph.prototype.nextCommand = function () { - var cm = this.element, - tb, - nb, - cs; - if (cm instanceof ScriptsMorph) { - this.shiftScript(new Point(0, 50)); - return; - } - while (!(cm instanceof CommandBlockMorph)) { - cm = cm.parent; - if (cm instanceof ScriptsMorph) { - return; - } - } - if (this.atEnd) { - cs = cm.parentThatIsA(CommandSlotMorph); - if (cs) { - this.element = cs.parentThatIsA(CommandBlockMorph); - this.atEnd = false; - this.nextCommand(); - } else { - tb = cm.topBlock().parentThatIsA(CommandBlockMorph); - if (tb) { - this.element = tb; - this.atEnd = false; - if (this.element instanceof HatBlockMorph) { - this.nextCommand(); - } - } - } - } else { - nb = cm.nextBlock(); - if (nb) { - this.element = nb; - } else { - this.element = cm; - this.atEnd = true; - } - } - this.fixLayout(); -}; - -ScriptFocusMorph.prototype.nextScript = function () { - var scripts = this.sortedScripts(), - idx; - if (scripts.length < 1) {return; } - if (this.element instanceof ScriptsMorph) { - this.element = scripts[0]; - } - idx = scripts.indexOf(this.element.topBlock()) + 1; - if (idx >= scripts.length) {idx = 0; } - this.element = scripts[idx]; - this.element.scrollIntoView(); - this.atEnd = false; - if (this.element instanceof HatBlockMorph) { - return this.nextElement(); - } - this.fixLayout(); -}; - -ScriptFocusMorph.prototype.lastScript = function () { - var scripts = this.sortedScripts(), - idx; - if (scripts.length < 1) {return; } - if (this.element instanceof ScriptsMorph) { - this.element = scripts[0]; - } - idx = scripts.indexOf(this.element.topBlock()) - 1; - if (idx < 0) {idx = scripts.length - 1; } - this.element = scripts[idx]; - this.element.scrollIntoView(); - this.atEnd = false; - if (this.element instanceof HatBlockMorph) { - return this.nextElement(); - } - this.fixLayout(); -}; - -ScriptFocusMorph.prototype.shiftScript = function (deltaPoint) { - var tb; - if (this.element instanceof ScriptsMorph) { - this.moveBy(deltaPoint); - } else { - tb = this.element.topBlock(); - if (tb && !(tb instanceof PrototypeHatBlockMorph)) { - tb.moveBy(deltaPoint); - } - } - this.editor.adjustBounds(); - this.fixLayout(); -}; - -ScriptFocusMorph.prototype.newScript = function () { - var pos = this.position(); - if (!(this.element instanceof ScriptsMorph)) { - pos = this.element.topBlock().fullBounds().bottomLeft().add( - new Point(0, 50) - ); - } - this.setPosition(pos); - this.element = this.editor; - this.editor.adjustBounds(); - this.fixLayout(); -}; - -ScriptFocusMorph.prototype.runScript = function () { - if (this.element instanceof ScriptsMorph) {return; } - this.element.topBlock().mouseClickLeft(); -}; - -ScriptFocusMorph.prototype.items = function () { - if (this.element instanceof ScriptsMorph) {return []; } - var script = this.element.topBlock(); - return script.allChildren().filter(each => - each instanceof SyntaxElementMorph && - !(each instanceof TemplateSlotMorph) && - (!each.isStatic || - each.choices || - each instanceof BooleanSlotMorph || - each instanceof RingMorph || - each instanceof MultiArgMorph || - each instanceof CommandSlotMorph - ) - ); -}; - -ScriptFocusMorph.prototype.sortedScripts = function () { - var scripts = this.editor.children.filter(each => - each instanceof BlockMorph - ); - scripts.sort((a, b) => - // make sure the prototype hat block always stays on top - a instanceof PrototypeHatBlockMorph ? 0 : a.top() - b.top() - ); - return scripts; -}; - -// ScriptFocusMorph undo / redo - -ScriptFocusMorph.prototype.undrop = function () { - this.editor.undrop(); -}; - -ScriptFocusMorph.prototype.redrop = function () { - this.editor.redrop(); -}; - -// ScriptFocusMorph block types - -ScriptFocusMorph.prototype.blockTypes = function () { - // answer an array of possible block types that fit into - // the current situation, NULL if no block can be inserted - - if (this.element.isTemplate) {return null; } - if (this.element instanceof ScriptsMorph) { - return ['hat', 'command', 'reporter', 'predicate', 'ring']; - } - if (this.element instanceof HatBlockMorph || - this.element instanceof CommandSlotMorph) { - return ['command']; - } - if (this.element instanceof CommandBlockMorph) { - if (this.atEnd && this.element.isStop()) { - return null; - } - if (this.element.parent instanceof ScriptsMorph) { - return ['hat', 'command']; - } - return ['command']; - } - if (this.element instanceof ReporterBlockMorph) { - if (this.element.getSlotSpec() === '%n') { - return ['reporter']; - } - return ['reporter', 'predicate', 'ring']; - } - if (this.element.getSpec() === '%n') { - return ['reporter']; - } - if (this.element.isStatic) { - return null; - } - return ['reporter', 'predicate', 'ring']; -}; - - -// ScriptFocusMorph keyboard events - -ScriptFocusMorph.prototype.processKeyDown = function (event) { - this.processKeyEvent( - event, - this.reactToKeyEvent - ); -}; - -ScriptFocusMorph.prototype.processKeyUp = function (event) { - nop(event); -}; - -ScriptFocusMorph.prototype.processKeyPress = function (event) { - nop(event); -}; - - -ScriptFocusMorph.prototype.processKeyEvent = function (event, action) { - var keyName, ctrl, shift; - - //console.log(event.keyCode); - this.world().hand.destroyTemporaries(); // remove result bubbles, if any - switch (event.keyCode) { - case 8: - keyName = 'backspace'; - break; - case 9: - keyName = 'tab'; - break; - case 13: - keyName = 'enter'; - break; - case 16: - case 17: - case 18: - return; - case 27: - keyName = 'esc'; - break; - case 32: - keyName = 'space'; - break; - case 37: - keyName = 'left arrow'; - break; - case 39: - keyName = 'right arrow'; - break; - case 38: - keyName = 'up arrow'; - break; - case 40: - keyName = 'down arrow'; - break; - default: - keyName = String.fromCharCode(event.keyCode || event.charCode); - } - ctrl = (event.ctrlKey || event.metaKey) ? 'ctrl ' : ''; - shift = event.shiftKey ? 'shift ' : ''; - keyName = ctrl + shift + keyName; - action.call(this, keyName); -}; - -ScriptFocusMorph.prototype.reactToKeyEvent = function (key) { - var evt = key.toLowerCase(), - shift = 50, - types, - vNames; - - // console.log(evt); - switch (evt) { - case 'esc': - return this.stopEditing(); - case 'enter': - return this.trigger(); - case 'shift enter': - return this.newScript(); - case 'ctrl shift enter': - return this.runScript(); - case 'space': - return this.menu(); - case 'left arrow': - return this.lastElement(); - case 'shift left arrow': - return this.shiftScript(new Point(-shift, 0)); - case 'right arrow': - return this.nextElement(); - case 'shift right arrow': - return this.shiftScript(new Point(shift, 0)); - case 'up arrow': - return this.lastCommand(); - case 'shift up arrow': - return this.shiftScript(new Point(0, -shift)); - case 'down arrow': - return this.nextCommand(); - case 'shift down arrow': - return this.shiftScript(new Point(0, shift)); - case 'tab': - return this.nextScript(); - case 'shift tab': - return this.lastScript(); - case 'backspace': - return this.deleteLastElement(); - case 'ctrl z': - return this.undrop(); - case 'ctrl y': - case 'ctrl shift z': - return this.redrop(); - case 'ctrl [': // ignore the first press of the Mac cmd key - return; - default: - types = this.blockTypes(); - if (!(this.element instanceof ScriptsMorph) && - types && contains(types, 'reporter')) { - vNames = Object.keys(this.element.getVarNamesDict()); - } - if (types) { - delete this.fps; - delete this.step; - this.show(); - this.editor.scriptTarget().searchBlocks( - key, - types, - vNames, - this - ); - } - } -}; - - -/* -// register examples with the World demo menu -// comment out to shave off a millisecond loading speed ;-) - -(function () { - var h, b, c, ci, cb, cm, cd, co, cl, cu, cs, cmd, rings, rc, scripts; - // SyntaxElementMorph.prototype.setScale(2.5); - - h = new HatBlockMorph(); - h.setSpec('When $greenflag pressed'); - - b = new ReporterBlockMorph(true); - b.setSpec('%bool'); - - c = new CommandBlockMorph(); - c.setSpec('this is a test $globe'); - - ci = new CommandBlockMorph(); - ci.setSpec('block with input %s unit %mult%n number'); - - cb = new CommandBlockMorph(); - cb.setSpec('bool %b ?'); - - cd = new CommandBlockMorph(); - cd.setSpec('direction %dir degrees'); - - co = new CommandBlockMorph(); - co.setSpec('object %obj'); - - cl = new CommandBlockMorph(); - cl.setSpec('list %l'); - - cu = new CommandBlockMorph(); - cu.setSpec('list %upvar'); - - cs = new CommandBlockMorph(); - cs.setSpec('control %b %ca'); - - cmd = new CommandBlockMorph(); - cmd.setSpec('command %cmdRing'); - - rings = new CommandBlockMorph(); - rings.setSpec('reporter %repRing predicate %predRing'); - - rc = new ReporterBlockMorph(); - rc.setSpec('color %clr'); - - scripts = new ScriptsMorph(); - - BlockMorph.prototype.addToDemoMenu([ - 'Syntax', - [ - [h, 'hat'], - [b, 'predicate'], - [c, 'with label text'], - [ci, 'editable input slots'], - [cb, 'Boolean slot'], - [cm, 'menu input'], - [cd, 'direction input'], - [co, 'object input'], - [cl, 'list input'], - [cu, 'upvar input'], - [cs, 'loop input'], - [cmd, 'cmd ring input'], - [rings, 'reporter rings input'], - [rc, 'color input'], - [scripts, 'scripts'] - ] - ]); -})(); -*/ + return \ No newline at end of file From 814897c54a159711bc644a72cdbd7ab97e7c5d7e Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:32:12 +0000 Subject: [PATCH 065/132] fix --- src/blocks.js | 3605 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 3604 insertions(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index 2657bca802..9d1ae4fc2c 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -13354,4 +13354,3607 @@ ArrowMorph.prototype.getRenderColor = function () { if (MorphicPreferences.isFlat) { return this.color; } - return \ No newline at end of file + return this.parent.color; + } + return this.color; +}; + +// TextSlotMorph ////////////////////////////////////////////////////// + +/* + I am a multi-line input slot, primarily used in Snap's code-mapping + blocks. +*/ + +// TextSlotMorph inherits from InputSlotMorph: + +TextSlotMorph.prototype = new InputSlotMorph(); +TextSlotMorph.prototype.constructor = TextSlotMorph; +TextSlotMorph.uber = InputSlotMorph.prototype; + +// TextSlotMorph instance creation: + +function TextSlotMorph(text, isNumeric, choiceDict, isReadOnly) { + this.init(text, isNumeric, choiceDict, isReadOnly); +} + +TextSlotMorph.prototype.init = function ( + text, + isNumeric, + choiceDict, + isReadOnly +) { + var contents = new InputSlotTextMorph(''), + arrow = new ArrowMorph( + 'down', + 0, + Math.max(Math.floor(this.fontSize / 6), 1), + BLACK, + true + ); + + contents.fontSize = this.fontSize; + contents.fixLayout(); + + this.isUnevaluated = false; + this.choices = choiceDict || null; // object, function or selector + this.oldContentsExtent = contents.extent(); + this.isNumeric = isNumeric || false; + this.isReadOnly = isReadOnly || false; + this.minWidth = 0; // can be chaged for text-type inputs ("landscape") + this.constant = null; + + InputSlotMorph.uber.init.call(this, null, null, null, null, true); // sil. + this.color = WHITE; + this.add(contents); + this.add(arrow); + contents.isEditable = true; + contents.isDraggable = false; + contents.enableSelecting(); + this.setContents(text); + +}; + +// TextSlotMorph accessing: + +TextSlotMorph.prototype.getSpec = function () { + if (this.isNumeric) { + return '%mlt'; + } + return '%mlt'; // default +}; + +TextSlotMorph.prototype.contents = function () { + return detect( + this.children, + child => child instanceof TextMorph + ); +}; + +// TextSlotMorph events: + +TextSlotMorph.prototype.layoutChanged = function () { + this.fixLayout(); +}; + +// ColorSlotMorph ////////////////////////////////////////////////////// + +/* + I am an editable input slot for a color. Users can edit my color by + clicking on me, in which case a display a color gradient palette + and let the user select another color. Note that the user isn't + restricted to selecting a color from the palette, any color from + anywhere within the World can be chosen. + + my block spec is %clr + + evaluate() returns my color +*/ + +// ColorSlotMorph inherits from ArgMorph: + +ColorSlotMorph.prototype = new ArgMorph(); +ColorSlotMorph.prototype.constructor = ColorSlotMorph; +ColorSlotMorph.uber = ArgMorph.prototype; + +// ColorSlotMorph instance creation: + +function ColorSlotMorph(clr) { + this.init(clr); +} + +ColorSlotMorph.prototype.init = function (clr) { + ColorSlotMorph.uber.init.call(this); + this.alpha = 1; + this.setColor(clr || new Color(145, 26, 68)); +}; + +ColorSlotMorph.prototype.getSpec = function () { + return '%clr'; +}; + +// ColorSlotMorph color sensing: + +ColorSlotMorph.prototype.getUserColor = function () { + var myself = this, + world = this.world(), + hand = world.hand, + posInDocument = getDocumentPositionOf(world.worldCanvas), + mouseMoveBak = hand.processMouseMove, + mouseDownBak = hand.processMouseDown, + mouseUpBak = hand.processMouseUp, + pal = new ColorPaletteMorph(null, new Point( + this.fontSize * 16, + this.fontSize * 10 + )), + ctx; + world.add(pal); + pal.setPosition(this.bottomLeft().add(new Point(0, this.edge))); + + // cache the world surface property (its full image) + // to prevent memory issues from constantly generating + // huge canvasses and and reading back pixel data only once + // note: this optimization makes it hard / impossible for the + // user to "catch" and sample the color of moving sprites + // but without it Chrome crashes as of Fall 2023 + ctx = Morph.prototype.fullImage.call(world).getContext('2d'); + + hand.processMouseMove = function (event) { + var pos = hand.position(), + dta = ctx.getImageData(pos.x, pos.y, 1, 1).data; + hand.setPosition(new Point( + event.pageX - posInDocument.x, + event.pageY - posInDocument.y + )); + myself.setColor(new Color(dta[0], dta[1], dta[2])); + }; + + hand.processMouseDown = nop; + + hand.processMouseUp = function () { + pal.destroy(); + hand.processMouseMove = mouseMoveBak; + hand.processMouseDown = mouseDownBak; + hand.processMouseUp = mouseUpBak; + }; +}; + +// ColorSlotMorph events: + +ColorSlotMorph.prototype.mouseClickLeft = function () { + this.selectForEdit().getUserColor(); +}; + +// ColorSlotMorph evaluating: + +ColorSlotMorph.prototype.evaluate = function () { + return this.color; +}; + +// ColorSlotMorph drawing: + +ColorSlotMorph.prototype.fixLayout = function () { + // determine my extent + var side = this.fontSize + this.edge * 2 + this.typeInPadding * 2; + this.bounds.setWidth(side); + this.bounds.setHeight(side); +}; + +ColorSlotMorph.prototype.render = function (ctx) { + var borderColor; + + if (this.parent) { + borderColor = this.parent.color; + } else { + borderColor = new Color(120, 120, 120); + } + ctx.fillStyle = this.color.toString(); + + // cache my border colors + this.cachedClr = borderColor.toString(); + this.cachedClrBright = borderColor.lighter(this.contrast) + .toString(); + this.cachedClrDark = borderColor.darker(this.contrast).toString(); + + ctx.fillRect( + this.edge, + this.edge, + this.width() - this.edge * 2, + this.height() - this.edge * 2 + ); + if (!MorphicPreferences.isFlat) { + this.drawRectBorder(ctx); + } +}; + +ColorSlotMorph.prototype.drawRectBorder = + InputSlotMorph.prototype.drawRectBorder; + +// BlockHighlightMorph ///////////////////////////////////////////////// + +/* + I am a glowing halo around a block or stack of blocks indicating that + a script is currently active or has encountered an error. + I halso have an optional readout that can display a thread count + if more than one process shares the same script +*/ + +// BlockHighlightMorph inherits from Morph: + +BlockHighlightMorph.prototype = new Morph(); +BlockHighlightMorph.prototype.constructor = BlockHighlightMorph; +BlockHighlightMorph.uber = Morph.prototype; + +// BlockHighlightMorph instance creation: + +function BlockHighlightMorph() { + this.threadCount = 0; + this.init(); +} + +BlockHighlightMorph.prototype.init = function () { + BlockHighlightMorph.uber.init.call(this); + this.isCachingImage = true; +}; + +// BlockHighlightMorph thread count readout + +BlockHighlightMorph.prototype.readout = function () { + return this.children.length ? this.children[0] : null; +}; + +BlockHighlightMorph.prototype.updateReadout = function () { + var readout = this.readout(), + inset = useBlurredShadows && !MorphicPreferences.isFlat ? + SyntaxElementMorph.prototype.activeBlur * 0.4 + : SyntaxElementMorph.prototype.activeBorder * -2; + if (this.threadCount < 2) { + if (readout) { + readout.destroy(); + } + return; + } + if (readout) { + readout.changed(); + readout.contents = this.threadCount.toString(); + readout.fixLayout(); + readout.rerender(); + } else { + readout = new SpeechBubbleMorph( + this.threadCount.toString(), + this.color, // color, + null, // edge, + null, // border, + this.color.darker(), // borderColor, + null, // padding, + 1, // isThought - don't draw a hook + true // no shadow - faster + ); + this.add(readout); + } + readout.setPosition(this.position().add(inset)); +}; + +// MultiArgMorph /////////////////////////////////////////////////////// + +/* + I am an arity controlled list of input slots + + my block specs are + + %mult%x - where x is any single input slot + %inputs - for an additional text label 'with inputs' + + evaluation is handles by the interpreter +*/ + +// MultiArgMorph inherits from ArgMorph: + +MultiArgMorph.prototype = new ArgMorph(); +MultiArgMorph.prototype.constructor = MultiArgMorph; +MultiArgMorph.uber = ArgMorph.prototype; + +// MultiArgMorph instance creation: + +function MultiArgMorph( + slotSpec, + labelTxt, + min, + eSpec, + arrowColor, + labelColor, + shadowColor, + shadowOffset, + isTransparent, + infix, + collapse, + defaults, + group +) { + this.init( + slotSpec, + labelTxt, + min, + eSpec, + arrowColor, + labelColor, + shadowColor, + shadowOffset, + isTransparent, + infix, + collapse, + defaults, + group + ); +} + +MultiArgMorph.prototype.init = function ( + slotSpec, // string or array of type strings + labelTxt, // string or array of prefix labels + min, + eSpec, + arrowColor, + labelColor, + shadowColor, + shadowOffset, + isTransparent, + infix, + collapse, + defaults, + group +) { + var label, + collapseLabel, + arrows = new FrameMorph(), + initial = min || 0, + listSymbol, + leftArrow, + rightArrow, + i; + + this.slotSpec = slotSpec || '%s'; + this.labelText = labelTxt instanceof Array ? + labelTxt.map(each => localize(each || '')) + : localize(labelTxt || ''); + this.infix = infix || ''; + this.collapse = localize(collapse || ''); + this.defaultValue = defaults || null; + this.groupInputs = 1; + this.initialSlots = isNil(initial) ? 1 : initial ; + this.minInputs = this.infix ? 0 : initial; + this.maxInputs = 0; + this.elementSpec = eSpec || null; + this.labelColor = labelColor || null; + this.shadowColor = shadowColor || null; + this.shadowOffset = shadowOffset || null; + + // in case an input group spec is specified, initialize it + this.initGroup(group); + + this.canBeEmpty = true; + MultiArgMorph.uber.init.call(this); + + // MultiArgMorphs are transparent by default b/c of zebra coloring + this.alpha = isTransparent === false ? 1 : 0; + arrows.alpha = isTransparent === false ? 1 : 0; + + // collapse label text: + if (this.collapse) { + collapseLabel = this.labelPart(this.collapse); + this.add(collapseLabel); + collapseLabel.hide(); + } + + // label text: + if (this.labelText || (this.slotSpec === '%cs')) { + label = this.labelPart( + this.labelText instanceof Array ? + this.labelText[0] + : this.labelText + ); + this.add(label); + label.hide(); + } + + // left arrow: + leftArrow = new ArrowMorph( + 'left', // direction + fontHeight(this.fontSize), // size + Math.max(Math.floor(this.fontSize / 6), 1), // padding + arrowColor, + true // isLbl + ); + + // right arrow: + rightArrow = new ArrowMorph( + 'right', // direction + fontHeight(this.fontSize), // size + Math.max(Math.floor(this.fontSize / 6), 1), // padding + arrowColor, + true // isLbl + ); + + // list symbol: + // listSymbol = this.labelPart('$verticalEllipsis-0.98'); + + // alternative list symbol designs to contemplate in the future: + // listSymbol = this.labelPart('$listNarrow-0.9'); + + /* + listSymbol = this.labelPart('$listNarrow-.98'); + listSymbol.backgroundColor = new Color(255, 140, 0); // list color + */ + + // /* + // listSymbol = new SymbolMorph('listNarrow', this.fontSize * 0.8); + listSymbol = new SymbolMorph('verticalEllipsis', this.fontSize); + listSymbol.alpha = 0.5; + listSymbol.getRenderColor = function () { + // behave the same as arrows when fading the blocks + if (MorphicPreferences.isFlat) { + return this.color; + } + return SyntaxElementMorph.prototype.alpha > 0.5 ? this.color : WHITE; + }; + // */ + + // control panel: + arrows.add(leftArrow); + arrows.add(rightArrow); + arrows.add(listSymbol); + arrows.rerender(); + arrows.acceptsDrops = false; + + this.add(arrows); + + // create the initial number of inputs + for (i = 0; i < initial; i += 1) { + this.addInput(); + } +}; + +MultiArgMorph.prototype.initGroup = function (aBlockSpec) { + var groupSpec, + words, + isSlot = word => word.startsWith('%') && word.length > 1, + labels = [], + part = []; + if (aBlockSpec) { + // translate block spec + groupSpec = BlockMorph.prototype.localizeBlockSpec(aBlockSpec); + // determine input slot specs + words = groupSpec.split(' '); + this.slotSpec = words.filter(word => isSlot(word)); + // determine group size + this.groupInputs = this.slotSpec.length; + // determine label texts + words.forEach(word => { + if (isSlot(word)) { + labels.push(part); + part = []; + } else { + part.push(word); + } + }); + // only add a postfix if it's non-empty + if (part.some(any => any.length)) { + labels.push(part); + } + this.labelText = labels.map(arr => arr.join(' ')); + } +}; + +MultiArgMorph.prototype.collapseLabel = function () { + return this.collapse ? this.children[0] : null; +}; + +MultiArgMorph.prototype.label = function () { + return this.labelText ? + this.children[this.collapse ? 1 : 0] + : null; +}; + +MultiArgMorph.prototype.allLabels = function () { + // including infix labels + return this.children.filter(m => m instanceof BlockLabelMorph); +}; + +MultiArgMorph.prototype.arrows = function () { + return this.children[this.children.length - 1]; +}; + +MultiArgMorph.prototype.listSymbol = function () { + return this.arrows().children[2]; +}; + +MultiArgMorph.prototype.getSpec = function () { + return '%mult' + this.slotSpec; +}; + +MultiArgMorph.prototype.setIrreplaceable = function (irreplaceable = false) { + this.isStatic = irreplaceable; + this.canBeEmpty = !irreplaceable; + this.fixLayout(); +}; + +MultiArgMorph.prototype.setInfix = function (separator = '') { + var inps; + if (this.infix === separator) { + return; + } + inps = this.inputs(); + this.collapseAll(); + this.infix = separator; + inps.forEach(slot => this.replaceInput(this.addInput(), slot)); + if (inps.length === 1 && this.infix) { // show at least 2 slots with infix + this.addInput(); + } +}; + +MultiArgMorph.prototype.setCollapse = function (collapse = '') { + var inps, coll, collapseLabel; + if (this.collapse === collapse) { + return; + } + coll = this.collapseLabel(); + inps = this.inputs(); + this.collapseAll(); + this.collapse = collapse; + this.removeChild(coll); // shouldn't matter if coll is null + if (this.collapse) { + collapseLabel = this.labelPart(this.collapse); + this.addChildFirst(collapseLabel); + collapseLabel.hide(); + } + inps.forEach(slot => this.replaceInput(this.addInput(), slot)); + if (inps.length === 1 && this.infix) { // show at least 2 slots with infix + this.addInput(); + } + this.fixLayout(); +}; + +MultiArgMorph.prototype.setExpand = function (expand) { + var inps, label; + + // parse expansion labels to determine its cardiinality + function massage(str) { + var items = (str || '').toString().split('\n').map(line => + line.trim()).filter(each => each.length); + return items.length > 1 ? items : items[0] || null; + } + + if (this.labelText === expand) { + return; + } + label = this.label(); + inps = this.inputs(); + this.collapseAll(); + this.labelText = massage(expand); + this.removeChild(label); // shouldn't matter if coll is null + if (this.labelText) { + label = this.labelPart( + this.labelText instanceof Array ? + this.labelText[0] + : this.labelText + ); + this.children.splice(this.collapse ? 1 : 0, null, label); + label.parent = this; + label.hide(); + } + inps.forEach(slot => this.replaceInput(this.addInput(), slot)); + if (inps.length === 1 && this.infix) { // show at least 2 slots with infix + this.addInput(); + } + this.fixLayout(); +}; + +MultiArgMorph.prototype.setDefaultValue = function (defaultValue) { + + // parse default values to determine their arity + function massage(str) { + var items = (str || '').toString().split('\n') + // .map(line => line.trim()) + .filter(each => each.length); + return items.length > 1 ? items : items[0] || null; + } + + if (this.defaultValue === defaultValue) { + return; + } + this.defaultValue = massage(defaultValue); +}; + +MultiArgMorph.prototype.setInitialSlots = function (initialSlots) { + this.initialSlots = Math.min(initialSlots, 12); +}; + +MultiArgMorph.prototype.setMinSlots = function (minSlots) { + this.minInputs = Math.min(minSlots, 12); +}; + +MultiArgMorph.prototype.setMaxSlots = function (maxSlots) { + this.maxInputs = +maxSlots; +}; + +// MultiArgMorph defaults: + +MultiArgMorph.prototype.setContents = function (anArray) { + var inputs = this.inputs(), i; + + if (!(anArray instanceof Array) && this.slotSpec === '%rcv') { + // special case for migrating former SEND block inputs to + // newer BROADCAST expansion slots for receivers + // this can be removed once all SEND blocks have been + // converted to v7 + anArray = [anArray]; + } + + for (i = 0; i < anArray.length; i += 1) { + if (anArray[i] !== null && (inputs[i])) { + inputs[i].setContents(anArray[i]); + } + } +}; + +// MultiArgMorph hiding and showing: + +/* + override the inherited behavior to recursively hide/show all + children, so that my instances get restored correctly when + switching back out of app mode. +*/ + +MultiArgMorph.prototype.hide = function () { + this.isVisible = false; + this.changed(); +}; + +MultiArgMorph.prototype.show = function () { + this.isVisible = true; + this.changed(); +}; + +// MultiArgMorph coloring: + +MultiArgMorph.prototype.setLabelColor = function ( + textColor, + shadowColor, + shadowOffset +) { + this.textColor = textColor; + this.shadowColor = shadowColor; + this.shadowOffset = shadowOffset; + MultiArgMorph.uber.setLabelColor.call( + this, + textColor, + shadowColor, + shadowOffset + ); +}; + +// MultiArgMorph layout: + +MultiArgMorph.prototype.fixLayout = function () { + var labels, shadowColor, shadowOffset, block; + if (this.slotSpec === '%t') { + this.isStatic = true; // in this case I cannot be exchanged + } + if (this.parent) { + labels = this.allLabels(); + this.color = this.parent.color; + this.arrows().color = this.color; + shadowColor = this.shadowColor || + this.parent.color.darker(this.labelContrast); + block = this.parentThatIsA(BlockMorph); + this.arrows().children[2].shadowColor = block ? + block.color.darker(this.labelContrast) + : shadowColor; + if (labels.length) { + labels.forEach(label => { + shadowOffset = this.shadowOffset || + (label ? label.shadowOffset : null); + if (!label.shadowColor.eq(shadowColor)) { + label.shadowColor = shadowColor; + label.shadowOffset = shadowOffset; + label.fixLayout(); + label.rerender(); + } + }); + } + } + this.fixArrowsLayout(); + MultiArgMorph.uber.fixLayout.call(this); + if (this.parent) { + this.parent.fixLayout(); + } +}; + +MultiArgMorph.prototype.fixArrowsLayout = function () { + var label = this.label(), + collapseLabel = this.collapseLabel(), + arrows = this.arrows(), + leftArrow = arrows.children[0], + rightArrow = arrows.children[1], + listSymbol = arrows.children[2], + inpCount = this.inputs().length, + dim = new Point(rightArrow.width() / 2, rightArrow.height()), + centerList = true; + leftArrow.show(); + listSymbol.show(); + rightArrow.show(); + arrows.setHeight(dim.y); + if (collapseLabel) { + collapseLabel.hide(); + } + if (this.isStatic) { + listSymbol.hide(); + } + if (inpCount < (this.minInputs + 1)) { // hide left arrow + if (label) { + label.hide(); + } + leftArrow.hide(); + if (this.isStatic) { + arrows.setWidth(dim.x); + } else { + if (collapseLabel) { + collapseLabel.show(); + } + arrows.setWidth(dim.x * 1.3 + listSymbol.width()); + listSymbol.setCenter(arrows.center()); + listSymbol.setLeft(arrows.left()); + centerList = false; + } + } else if (this.is3ArgRingInHOF() && inpCount > 2) { // hide right arrow + rightArrow.hide(); + arrows.width(dim.x); + } else { // show both arrows + if (label) { + label.show(); + } + arrows.setWidth(dim.x * 2.4 + (this.isStatic ? 0 : listSymbol.width())); + if (this.maxInputs && inpCount > this.maxInputs - 1) { + // hide right arrow + rightArrow.hide(); + arrows.setWidth(dim.x); + } + } + leftArrow.setCenter(arrows.center()); + leftArrow.setLeft(arrows.left()); + rightArrow.setCenter(arrows.center()); + rightArrow.setRight(arrows.right()); + if (centerList) { + listSymbol.setCenter(arrows.center()); + } + arrows.rerender(); +}; + +MultiArgMorph.prototype.fixHolesLayout = function () { + var pos; + this.holes = []; + if (this.slotSpec.includes('%cs')) { + pos = this.position(); + this.inputs().forEach(slot => { + if (slot instanceof CSlotMorph) { + slot.fixHolesLayout(); + this.holes.push( + slot.holes[0].translateBy(slot.position().subtract(pos)) + ); + } + }); + } +}; + +MultiArgMorph.prototype.refresh = function () { + this.inputs().forEach(input => { + input.fixLayout(); + input.rerender(); + }); +}; + +// MultiArgMorph deleting & inserting slots: +/* + caution, only call these methods with "primitive" inputs, + since they don't preserve embedded blocks (yes, on purpose) +*/ + +MultiArgMorph.prototype.deleteSlot = function (anInput) { + var len = this.inputs().length, + idx = this.children.indexOf(anInput), + block = this.parentThatIsA(BlockMorph), + sprite = block.scriptTarget(); + if (len <= this.minInputs) { + return; + } + if (this.infix) { + if (idx === (this.children.length - 2)) { // b/c arrows + this.removeChild(this.children[idx - 1]); + } else { + this.removeChild(this.children[idx + 1]); + } + } + this.removeChild(anInput); + this.fixLayout(); + sprite.recordUserEdit( + 'scripts', + 'poly slot', + 'delete', + block.abstractBlockSpec() + ); +}; + +MultiArgMorph.prototype.insertNewInputBefore = function (anInput, contents) { + var idx = this.children.indexOf(anInput), + newPart = this.labelPart(this.slotSpec), + block = this.parentThatIsA(BlockMorph), + sprite = block.scriptTarget(), + infix; + + if (this.maxInputs && (this.inputs().length >= this.maxInputs)) { + return; + } + if (contents) { + newPart.setContents(contents); + } + newPart.parent = this; + if (this.infix) { + infix = this.labelPart(localize(this.infix)); + infix.parent = this; + this.children.splice(idx, 0, newPart, infix); + } else { + this.children.splice(idx, 0, newPart); + } + newPart.fixLayout(); + if (this.parent instanceof BlockMorph) { + this.parent.fixLabelColor(); + } + this.fixLayout(); + sprite.recordUserEdit( + 'scripts', + 'poly slot', + 'insert', + block.abstractBlockSpec() + ); + return newPart; +}; + +// MultiArgMorph arity control: + +MultiArgMorph.prototype.addInput = function (contents) { + var len = this.inputs().length, + newPart = this.labelPart(this.slotSpecFor(len)), + value = isNil(contents) ? this.defaultValueFor(len) : contents, + i, name, idx; + + this.addInfix(); + idx = this.children.length - 1; + if (value !== '' && !isNil(value)) { + newPart.setContents(value); + } else if (this.elementSpec === '%scriptVars' || + this.elementSpec === '%blockVars') { + name = ''; + i = idx; + if (this.elementSpec === '%scriptVars') { + // compensate for missing label element + i += 1; + } + while (i > 0) { + name = String.fromCharCode(97 + (i - 1) % 26) + name; + i = Math.floor((i - 1) / 26); + } + newPart.setContents(name); + } else if (contains(['%parms', '%ringparms'], this.elementSpec)) { + if (this.is3ArgRingInHOF() && idx < 5) { + newPart.setContents([ + localize('value'), + localize('index'), + localize('list') + ][idx - 1]); + } else { + newPart.setContents('#' + idx); + } + } else if (this.elementSpec === '%message') { + newPart.setContents(localize('data')); + } else if (this.elementSpec === '%keyName') { + newPart.setContents(localize('key')); + } + newPart.parent = this; + this.children.splice(idx, 0, newPart); + this.addPostfix(); + newPart.fixLayout(); + if (this.parent instanceof BlockMorph) { + this.parent.fixLabelColor(); + } + this.fixLayout(); + return newPart; +}; + +MultiArgMorph.prototype.addInfix = function () { + var infix, + len = this.inputs().length, + label = this.infix ? localize(this.infix) + : (this.labelText instanceof Array ? + (this.slotSpec instanceof Array ? + this.labelText[len % this.slotSpec.length] + : this.labelText[len % this.labelText.length]) + : ''); + + if (label === '' || !len || this.children.length < 2) {return; } + infix = this.labelPart(label); + infix.parent = this; + this.children.splice(this.children.length - 1, 0, infix); +}; + +MultiArgMorph.prototype.addPostfix = function () { + var postfix; + if (this.labelText instanceof Array && + this.slotSpec instanceof Array && + this.inputs().length % this.slotSpec.length === 0 && + this.labelText.length === (this.slotSpec.length + 1) + ) { + postfix = this.labelPart(this.labelText[this.slotSpec.length]); + postfix.parent = this; + this.children.splice(this.children.length - 1, 0, postfix); + } +}; + +MultiArgMorph.prototype.removePostfix = function (idx) { + if (this.labelText instanceof Array && + idx % this.slotSpec.length === 0 && + this.labelText.length === (this.slotSpec.length + 1) + ) { + this.removeChild(this.children[this.children.length - 2]); + } +}; + +MultiArgMorph.prototype.removeInput = function () { + var len = this.inputs().length, + oldPart, scripts; + if (len > 0) { + this.removePostfix(len); + oldPart = this.inputs()[len - 1]; + this.removeChild(oldPart); + if (oldPart instanceof CSlotMorph) { + oldPart = oldPart.nestedBlock(); + } + if (oldPart instanceof BlockMorph && + !(oldPart instanceof RingMorph && !oldPart.contents())) { + scripts = this.parentThatIsA(ScriptsMorph); + if (scripts) { + oldPart.moveBy(10); + scripts.add(oldPart); + } + } + } + if (this.infix || + (this.labelText instanceof Array && this.inputs().length) + ) { + if (this.children.length > (this.collapse ? 2 : 1) && + !(this.labelText instanceof Array && + this.labelText[this.inputs().length % this.slotSpec.length] + === '') + ) { + this.removeChild(this.children[this.children.length - 2]); + } + } + this.fixLayout(); +}; + +MultiArgMorph.prototype.collapseAll = function () { + var len = this.inputs().length, + i; + for (i = 0; i < len; i+= 1) { + this.removeInput(); + } +}; + +MultiArgMorph.prototype.isVertical = function () { + return contains(['%repRing', '%predRing', '%cmdRing'], this.slotSpec); +}; + +MultiArgMorph.prototype.is3ArgRingInHOF = function () { + // answer true if I am embedded into a ring inside a HOF block + // that supports 3 parameters ("item, idx, data") + // of which there are currently only MAP, KEEP and FIND + // and their atomic counterparts + var ring = this.parent, + block; + if (ring) { + block = ring.parent; + if (block instanceof ReporterBlockMorph) { + return block.inputs()[0] === ring && + contains( + [ + 'reportMap', + 'reportAtomicMap', + 'reportKeep', + 'reportAtomicKeep', + 'reportFindFirst', + 'reportAtomicFindFirst' + ], + block.selector + ); + } + } + return false; +}; + +MultiArgMorph.prototype.slotSpecFor = function (index) { + return this.slotSpec instanceof Array ? + this.slotSpec[index % this.slotSpec.length] + : this.slotSpec; +}; + +MultiArgMorph.prototype.defaultValueFor = function (index) { + var dta = this.defaultValueDataFor(index); + return this.parentThatIsA(BlockMorph)?.definition?.selector ? + localize(dta) : dta; +}; + +MultiArgMorph.prototype.defaultValueDataFor = function (index) { + // private - answer the raw untranslated data + // repeat & wrap default values inside label groups + if (!this.parent || this.groupInputs > 1) { + return this.defaultValue instanceof Array ? + this.defaultValue[index % this.defaultValue.length] + : this.defaultValue; + } + + // otherwise use them just once each + if (this.defaultValue instanceof Array) { + return this.defaultValue[index] || ''; + } + return index ? '' : this.defaultValue; +}; + +// MultiArgMorph events: + +MultiArgMorph.prototype.mouseClickLeft = function (pos) { + // prevent expansion in the palette + // (because it can be hard or impossible to collapse again) + var block = this.parentThatIsA(BlockMorph), + sprite = block.scriptTarget(); + if (!this.parentThatIsA(ScriptsMorph)) { + this.escalateEvent('mouseClickLeft', pos); + return; + } + // if the key is pressed, repeat action 3 times + var target = this.selectForEdit(), + arrows = target.arrows(), + leftArrow = arrows.children[0], + rightArrow = arrows.children[1], + arrowsBounds = target.arrows().bounds.expandBy(this.fontSize / 3), + arrowsCenter = arrows.center().x, + isExpansionClick, + repetition = this.groupInputs * + (target.world().currentKey === 16 ? 3 : 1), + i; + + if (arrowsBounds.containsPoint(pos)) { + if (leftArrow.isVisible && rightArrow.isVisible) { + isExpansionClick = pos.x >= arrowsCenter; + } else { + isExpansionClick = rightArrow.isVisible; + } + if (isExpansionClick) { // right arrow + if (this.infix && !this.inputs().length) { + repetition = Math.max(repetition, 2); + } + for (i = 0; i < repetition; i += 1) { + if (rightArrow.isVisible) { + target.addInput(); + } + } + sprite.recordUserEdit( + 'scripts', + 'poly slot', + 'expand', + block.abstractBlockSpec() + ); + } else { // left arrow + if (this.infix && this.inputs().length < 3) { + repetition = 2; + } + for (i = 0; i < repetition; i += 1) { + if (leftArrow.isVisible) { + target.removeInput(); + } + } + sprite.recordUserEdit( + 'scripts', + 'poly slot', + 'collapse', + block.abstractBlockSpec() + ); + } + } else { + target.escalateEvent('mouseClickLeft', pos); + } +}; + +// MultiArgMorph menu: + +MultiArgMorph.prototype.userMenu = function () { + var menu = new MenuMorph(this), + block = this.parentThatIsA(BlockMorph), + key = ''; + if (!StageMorph.prototype.enableCodeMapping) { + return this.parent.userMenu(); + } + if (block) { + if (block instanceof RingMorph) { + key = 'parms_'; + } else if (block.selector === 'doDeclareVariables') { + key = 'tempvars_'; + } + } + menu.addItem( + 'code list mapping...', + () => this.mapCodeList(key) + ); + menu.addItem( + 'code item mapping...', + () => this.mapCodeItem(key) + ); + menu.addItem( + 'code delimiter mapping...', + () => this.mapCodeDelimiter(key) + ); + return menu; +}; + +// MultiArgMorph code mapping + +/* + code mapping lets you use blocks to generate arbitrary text-based + source code that can be exported and compiled / embedded elsewhere, + it's not part of Snap's evaluator and not needed for Snap itself +*/ + +MultiArgMorph.prototype.mapCodeDelimiter = function (key) { + this.mapToCode(key + 'delim', 'list item delimiter'); +}; + +MultiArgMorph.prototype.mapCodeList = function (key) { + this.mapToCode(key + 'list', 'list contents <#1>'); +}; + +MultiArgMorph.prototype.mapCodeItem = function (key) { + this.mapToCode(key + 'item', 'list item <#1>'); +}; + +MultiArgMorph.prototype.mapToCode = function (key, label) { + // private - open a dialog box letting the user map code via the GUI + new DialogBoxMorph( + this, + code => StageMorph.prototype.codeMappings[key] = code, + this + ).promptCode( + 'Code mapping - ' + label, + StageMorph.prototype.codeMappings[key] || '', + this.world() + ); +}; + +MultiArgMorph.prototype.mappedCode = function (definitions) { + var block = this.parentThatIsA(BlockMorph), + key = '', + code, + items = '', + itemCode, + delim, + count = 0, + parts = []; + + if (block) { + if (block instanceof RingMorph) { + key = 'parms_'; + } else if (block.selector === 'doDeclareVariables') { + key = 'tempvars_'; + } + } + + code = StageMorph.prototype.codeMappings[key + 'list'] || '<#1>'; + itemCode = StageMorph.prototype.codeMappings[key + 'item'] || '<#1>'; + delim = StageMorph.prototype.codeMappings[key + 'delim'] || ' '; + + this.inputs().forEach(input => + parts.push(itemCode.replace(/<#1>/g, input.mappedCode(definitions))) + ); + parts.forEach(part => { + if (count) { + items += delim; + } + items += part; + count += 1; + }); + code = code.replace(/<#1>/g, items); + return code; +}; + +// MultiArgMorph arity evaluating: + +MultiArgMorph.prototype.evaluate = function () { + // this is usually overridden by the interpreter. This method is only + // called (and needed) for the variables menu. + + var result = []; + this.inputs().forEach(slot => + result.push(slot.evaluate()) + ); + return result; +}; + +MultiArgMorph.prototype.isEmptySlot = function () { + return this.canBeEmpty ? this.inputs().length === 0 : false; +}; + +// MultiArgMorph op-sequence analysis + +MultiArgMorph.prototype.unwind = BlockMorph.prototype.unwind; +MultiArgMorph.prototype.unwindAfter = BlockMorph.prototype.unwindAfter; + +// ArgLabelMorph /////////////////////////////////////////////////////// + +/* + I am a label string that is wrapped around an ArgMorph, usually + a MultiArgMorph, so to indicate that it has been replaced entirely + for an embedded reporter block + + I don't have a block spec, I get embedded automatically by the parent + block's argument replacement mechanism + + My evaluation method is the identity function, i.e. I simply pass my + input's value along. +*/ + +// ArgLabelMorph inherits from ArgMorph: + +ArgLabelMorph.prototype = new ArgMorph(); +ArgLabelMorph.prototype.constructor = ArgLabelMorph; +ArgLabelMorph.uber = ArgMorph.prototype; + +// MultiArgMorph instance creation: + +function ArgLabelMorph(argMorph, labelTxt) { + this.init(argMorph, labelTxt); +} + +ArgLabelMorph.prototype.init = function (argMorph, labelTxt) { + var label; + + this.labelText = localize(labelTxt || 'input list:'); + ArgLabelMorph.uber.init.call(this); + + this.isStatic = true; // I cannot be exchanged + + // ArgLabelMorphs are transparent + this.alpha = 0; + + // label text: + label = this.labelPart(this.labelText); + this.add(label); + + // argMorph + this.add(argMorph); +}; + +ArgLabelMorph.prototype.label = function () { + return this.children[0]; +}; + +ArgLabelMorph.prototype.argMorph = function () { + return this.children[1]; +}; + +// ArgLabelMorph layout: + +ArgLabelMorph.prototype.fixLayout = function () { + var label = this.label(), + shadowColor, + shadowOffset; + + if (this.parent) { + this.color = this.parent.color; + shadowOffset = label.shadowOffset || ZERO; + + // determine the shadow color for zebra coloring: + if (shadowOffset.x < 0) { + shadowColor = this.parent.color.darker(this.labelContrast); + } else { + shadowColor = this.parent.color.lighter(this.labelContrast); + } + + if (this.labelText !== '') { + if (!label.shadowColor.eq(shadowColor)) { + label.shadowColor = shadowColor; + label.shadowOffset = shadowOffset; + label.rerender(); + } + } + } + ArgLabelMorph.uber.fixLayout.call(this); + if (this.parent) { + this.parent.fixLayout(); + } +}; + +ArgLabelMorph.prototype.refresh = function () { + this.inputs().forEach(input => { + input.fixLayout(); + input.rerender(); + }); +}; + +// ArgLabelMorph label color: + +ArgLabelMorph.prototype.setLabelColor = function ( + textColor, + shadowColor, + shadowOffset +) { + if (this.labelText !== '') { + var label = this.label(); + label.color = textColor; + label.shadowColor = shadowColor; + label.shadowOffset = shadowOffset; + label.rerender(); + } +}; + +// ArgLabelMorph events: + +ArgLabelMorph.prototype.reactToGrabOf = function () { + if (this.parent instanceof SyntaxElementMorph) { + this.parent.revertToDefaultInput(this); + } +}; + +// ArgLabelMorph evaluating: + +ArgLabelMorph.prototype.evaluate = function () { + // this is usually overridden by the interpreter. This method is only + // called (and needed) for the variables menu. + + return this.argMorph().evaluate(); +}; + +ArgLabelMorph.prototype.isEmptySlot = function () { + return false; +}; + +// FunctionSlotMorph /////////////////////////////////////////////////// + +/* + I am an unevaluated, non-editable, rf-colored, rounded or diamond + input slot. My current (only) use is in the THE BLOCK block. + + My command spec is %f +*/ + +// FunctionSlotMorph inherits from ArgMorph: + +FunctionSlotMorph.prototype = new ArgMorph(); +FunctionSlotMorph.prototype.constructor = FunctionSlotMorph; +FunctionSlotMorph.uber = ArgMorph.prototype; + +// FunctionSlotMorph instance creation: + +function FunctionSlotMorph(isPredicate) { + this.init(isPredicate); +} + +FunctionSlotMorph.prototype.init = function (isPredicate) { + FunctionSlotMorph.uber.init.call(this); + this.isPredicate = isPredicate || false; + this.color = this.rfColor; +}; + +FunctionSlotMorph.prototype.getSpec = function () { + return '%f'; +}; + +// FunctionSlotMorph drawing: + +FunctionSlotMorph.prototype.render = function (ctx) { + var borderColor; + + if (this.parent) { + borderColor = this.parent.color; + } else { + borderColor = new Color(120, 120, 120); + } + + // cache my border colors + this.cachedClr = borderColor.toString(); + this.cachedClrBright = borderColor.lighter(this.contrast) + .toString(); + this.cachedClrDark = borderColor.darker(this.contrast).toString(); + + if (this.isPredicate) { + this.drawDiamond(ctx); + } else { + this.drawRounded(ctx); + } +}; + +FunctionSlotMorph.prototype.drawRounded = function (ctx) { + var h = this.height(), + r = Math.min(this.rounding, h / 2), + w = this.width(), + shift = this.edge / 2, + gradient; + + // draw the 'flat' shape: + ctx.fillStyle = this.color.toString(); + ctx.beginPath(); + + // top left: + ctx.arc( + r, + r, + r, + radians(-180), + radians(-90), + false + ); + + // top right: + ctx.arc( + w - r, + r, + r, + radians(-90), + radians(-0), + false + ); + + // bottom right: + ctx.arc( + w - r, + h - r, + r, + radians(0), + radians(90), + false + ); + + // bottom left: + ctx.arc( + r, + h - r, + r, + radians(90), + radians(180), + false + ); + + ctx.closePath(); + ctx.fill(); + + if (MorphicPreferences.isFlat) {return; } + + // add 3D-Effect: + ctx.lineWidth = this.edge; + ctx.lineJoin = 'round'; + ctx.lineCap = 'round'; + + // bottom left corner + ctx.strokeStyle = this.cachedClr; //gradient; + ctx.beginPath(); + ctx.arc( + r, + h - r, + r - shift, + radians(90), + radians(180), + false + ); + ctx.stroke(); + + // top right corner + ctx.strokeStyle = this.cachedClr; //gradient; + ctx.beginPath(); + ctx.arc( + w - r, + r, + r - shift, + radians(-90), + radians(0), + false + ); + ctx.stroke(); + + // normal gradient edges + + if (useBlurredShadows) { + ctx.shadowOffsetX = shift; + ctx.shadowOffsetY = shift; + ctx.shadowBlur = this.edge; + ctx.shadowColor = this.color.darker(80).toString(); + } + + // top edge: straight line + gradient = ctx.createLinearGradient( + 0, + 0, + 0, + this.edge + ); + gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.cachedClr); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(r - shift, shift); + ctx.lineTo(w - r + shift, shift); + ctx.stroke(); + + // top edge: left corner + gradient = ctx.createRadialGradient( + r, + r, + r - this.edge, + r, + r, + r + ); + gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.cachedClrDark); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.arc( + r, + r, + r - shift, + radians(180), + radians(270), + false + ); + ctx.stroke(); + + // left edge: straight vertical line + gradient = ctx.createLinearGradient(0, 0, this.edge, 0); + gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.cachedClr); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(shift, r); + ctx.lineTo(shift, h - r); + ctx.stroke(); + + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 0; + ctx.shadowBlur = 0; + + // bottom edge: right corner + gradient = ctx.createRadialGradient( + w - r, + h - r, + r - this.edge, + w - r, + h - r, + r + ); + gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.cachedClrBright); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.arc( + w - r, + h - r, + r - shift, + radians(0), + radians(90), + false + ); + ctx.stroke(); + + // bottom edge: straight line + gradient = ctx.createLinearGradient( + 0, + h - this.edge, + 0, + h + ); + gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.cachedClrBright); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(r - shift, h - shift); + ctx.lineTo(w - r + shift, h - shift); + ctx.stroke(); + + // right edge: straight vertical line + gradient = ctx.createLinearGradient(w - this.edge, 0, w, 0); + gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.cachedClrBright); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(w - shift, r + shift); + ctx.lineTo(w - shift, h - r); + ctx.stroke(); + +}; + +FunctionSlotMorph.prototype.drawDiamond = function (ctx) { + var w = this.width(), + h = this.height(), + h2 = Math.floor(h / 2), + r = Math.min(this.rounding, h2), + shift = this.edge / 2, + gradient; + + // draw the 'flat' shape: + ctx.fillStyle = this.color.toString(); + ctx.beginPath(); + + ctx.moveTo(0, h2); + ctx.lineTo(r, 0); + ctx.lineTo(w - r, 0); + ctx.lineTo(w, h2); + ctx.lineTo(w - r, h); + ctx.lineTo(r, h); + + ctx.closePath(); + ctx.fill(); + + if (MorphicPreferences.isFlat) {return; } + + // add 3D-Effect: + ctx.lineWidth = this.edge; + ctx.lineJoin = 'round'; + ctx.lineCap = 'round'; + + // half-tone edges + // bottom left corner + ctx.strokeStyle = this.cachedClr; + ctx.beginPath(); + ctx.moveTo(shift, h2); + ctx.lineTo(r, h - shift); + ctx.stroke(); + + // top right corner + ctx.strokeStyle = this.cachedClr; + ctx.beginPath(); + ctx.moveTo(w - shift, h2); + ctx.lineTo(w - r, shift); + ctx.stroke(); + + // normal gradient edges + // top edge: left corner + + if (useBlurredShadows) { + ctx.shadowOffsetX = shift; + ctx.shadowOffsetY = shift; + ctx.shadowBlur = this.edge; + ctx.shadowColor = this.color.darker(80).toString(); + } + + gradient = ctx.createLinearGradient( + 0, + 0, + r, + 0 + ); + gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.cachedClr); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(shift, h2); + ctx.lineTo(r, shift); + ctx.stroke(); + + // top edge: straight line + gradient = ctx.createLinearGradient( + 0, + 0, + 0, + this.edge + ); + gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.cachedClr); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(r, shift); + ctx.lineTo(w - r, shift); + ctx.stroke(); + + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 0; + ctx.shadowBlur = 0; + + // bottom edge: right corner + gradient = ctx.createLinearGradient( + w - r, + 0, + w, + 0 + ); + gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.cachedClrBright); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(w - r, h - shift); + ctx.lineTo(w - shift, h2); + ctx.stroke(); + + // bottom edge: straight line + gradient = ctx.createLinearGradient( + 0, + h - this.edge, + 0, + h + ); + gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.cachedClrBright); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(r + shift, h - shift); + ctx.lineTo(w - r - shift, h - shift); + ctx.stroke(); +}; + +// ReporterSlotMorph /////////////////////////////////////////////////// + +/* + I am a ReporterBlock-shaped input slot. I can nest as well as + accept reporter blocks (containing reified scripts). + + my most important accessor is + + nestedBlock() - answer the reporter block I encompass, if any + + My command spec is %r for reporters (round) and %p for + predicates (diamond) + + evaluate() returns my nested block or null +*/ + +// ReporterSlotMorph inherits from FunctionSlotMorph: + +ReporterSlotMorph.prototype = new FunctionSlotMorph(); +ReporterSlotMorph.prototype.constructor = ReporterSlotMorph; +ReporterSlotMorph.uber = FunctionSlotMorph.prototype; + +// ReporterSlotMorph instance creation: + +function ReporterSlotMorph(isPredicate) { + this.init(isPredicate); +} + +ReporterSlotMorph.prototype.init = function (isPredicate) { + ReporterSlotMorph.uber.init.call(this, isPredicate, true); + this.add(this.emptySlot()); + this.fixLayout(); +}; + +ReporterSlotMorph.prototype.emptySlot = function () { + var empty = new ArgMorph(), + shrink = this.rfBorder * 2 + this.edge * 2; + empty.color = this.rfColor; + empty.alpha = 0; + empty.bounds.setExtent(new Point( + (this.fontSize + this.edge * 2) * 2 - shrink, + this.fontSize + this.edge * 2 - shrink + )); + return empty; +}; + +// ReporterSlotMorph accessing: + +ReporterSlotMorph.prototype.getSpec = function () { + return '%r'; +}; + +ReporterSlotMorph.prototype.contents = function () { + return this.children[0]; +}; + +ReporterSlotMorph.prototype.nestedBlock = function () { + var contents = this.contents(); + return contents instanceof ReporterBlockMorph ? contents : null; +}; + +// ReporterSlotMorph evaluating: + +ReporterSlotMorph.prototype.evaluate = function () { + return this.nestedBlock(); +}; + +ReporterSlotMorph.prototype.isEmptySlot = function () { + return this.nestedBlock() === null; +}; + +// ReporterSlotMorph layout: + +ReporterSlotMorph.prototype.fixLayout = function () { + var contents = this.contents(); + if (!contents) { + contents = this.emptySlot(); + this.add(contents); + } + this.bounds.setExtent(contents.extent().add( + this.edge * 2 + this.rfBorder * 2 + )); + contents.setCenter(this.center()); + if (this.parent) { + if (this.parent.fixLayout) { + this.parent.fixLayout(); + } + } +}; + +// RingReporterSlotMorph /////////////////////////////////////////////////// + +/* + I am a ReporterBlock-shaped input slot for use in RingMorphs. + I can nest reporter blocks (both round and diamond) as well + as command blocks (jigsaw shaped). + + My command spec is %rr for reporters (round) and %rp for + predicates (diamond) + + evaluate() returns my nested block or null + (inherited from ReporterSlotMorph +*/ + +// ReporterSlotMorph inherits from FunctionSlotMorph: + +RingReporterSlotMorph.prototype = new ReporterSlotMorph(); +RingReporterSlotMorph.prototype.constructor = RingReporterSlotMorph; +RingReporterSlotMorph.uber = ReporterSlotMorph.prototype; + +// ReporterSlotMorph preferences settings: + +RingReporterSlotMorph.prototype.rfBorder + = RingCommandSlotMorph.prototype.rfBorder; + +RingReporterSlotMorph.prototype.edge + = RingCommandSlotMorph.prototype.edge; + +RingReporterSlotMorph.prototype.enableCommandDrops = true; + +// RingReporterSlotMorph instance creation: + +function RingReporterSlotMorph(isPredicate) { + this.init(isPredicate); +} + +RingReporterSlotMorph.prototype.init = function (isPredicate) { + RingReporterSlotMorph.uber.init.call(this, isPredicate, true); + this.contrast = RingMorph.prototype.contrast; +}; + +// RingReporterSlotMorph accessing: + +RingReporterSlotMorph.prototype.getSpec = function () { + return '%rr'; +}; + +RingReporterSlotMorph.prototype.replaceInput = function ( + source, + target, + noVanish +) { + RingReporterSlotMorph.uber.replaceInput.call(this, source, target); + if (this.parent instanceof RingMorph && !noVanish) { + this.parent.vanishForSimilar(); + } +}; + +// RingReporterSlotMorph attach targets for commands: + +RingReporterSlotMorph.prototype.slotAttachPoint = + CommandSlotMorph.prototype.slotAttachPoint; + +RingReporterSlotMorph.prototype.dentLeft = + CommandSlotMorph.prototype.dentLeft; + +RingReporterSlotMorph.prototype.dentCenter = + CommandSlotMorph.prototype.dentCenter; + +RingReporterSlotMorph.prototype.attachTargets = function () { + if (!RingReporterSlotMorph.prototype.enableCommandDrops || + this.contents() instanceof ReporterBlockMorph + ) { + // don't let commands "kick out" embedded reporters + return []; + } + return CommandSlotMorph.prototype.attachTargets.call(this); +}; + +// RingReporterSlotMorph nesting for commands: + +RingReporterSlotMorph.prototype.nestedBlock = function (block) { + if (block) { + var nb = this.nestedBlock(); + this.replaceInput(this.children[0], block); + if (nb) { + block.bottomBlock().nextBlock(nb); + } + this.fixLayout(); + } else { + return detect( + this.children, + child => child instanceof BlockMorph + ); + } +}; + +// RingReporterSlotMorph layout: + +RingReporterSlotMorph.prototype.fixLayout = function () { + if (this.contents() instanceof CommandBlockMorph) { + CommandSlotMorph.prototype.fixLayout.call(this); + } else { + RingReporterSlotMorph.uber.fixLayout.call(this); + } +}; + +// RingReporterSlotMorph drawing: + +RingReporterSlotMorph.prototype.render = function (ctx) { + if (MorphicPreferences.isFlat) {return; } + + // init + this.cachedClr = this.color.toString(); + this.cachedClrBright = this.bright(); + this.cachedClrDark = this.dark(); + ctx.fillStyle = this.cachedClr; + + // only add 3D-Effect here, rendering of the flat shape happens at the + // encompassing block level + if (this.isPredicate) { + this.drawEdgesDiamond(ctx); + } else { + this.drawEdgesOval(ctx); + } +}; + +RingReporterSlotMorph.prototype.outlinePath = function (ctx, offset) { + if (this.isPredicate) { + this.outlinePathDiamond(ctx, offset); + } else { + this.outlinePathOval(ctx, offset); + } +}; + +RingReporterSlotMorph.prototype.outlinePathOval = function (ctx, offset) { + var ox = offset.x, + oy = offset.y, + w = this.width(), + h = this.height(), + r = Math.min(this.rounding, h / 2); + + // top left: + ctx.arc( + r + this.edge + ox, + r + this.edge + oy, + r, + radians(-180), + radians(-90), + false + ); + + // top right: + ctx.arc( + w - r - this.edge + ox, + r + this.edge + oy, + r, + radians(-90), + radians(-0), + false + ); + + // bottom right: + ctx.arc( + w - r - this.edge + ox, + h - r - this.edge + oy, + r, + radians(0), + radians(90), + false + ); + + // bottom left: + ctx.arc( + r + this.edge + ox, + h - r - this.edge + oy, + r, + radians(90), + radians(180), + false + ); + + // "close" the path + ctx.lineTo(this.edge + ox, r + this.edge + oy); +}; + +RingReporterSlotMorph.prototype.drawEdgesOval = function (ctx) { + var h = this.height(), + r = Math.min(this.rounding, h / 2), + w = this.width(), + shift = this.edge / 2, + gradient; + + + // add 3D-Effect: + ctx.lineWidth = this.edge; + ctx.lineJoin = 'round'; + ctx.lineCap = 'round'; + + // bottom left corner + ctx.strokeStyle = this.cachedClr; + ctx.beginPath(); + ctx.arc( + r, + h - r, + r - shift, + radians(90), + radians(180), + false + ); + ctx.stroke(); + + // top right corner + ctx.strokeStyle = this.cachedClr; + ctx.beginPath(); + ctx.arc( + w - r, + r, + r - shift, + radians(-90), + radians(0), + false + ); + ctx.stroke(); + + // normal gradient edges + + if (useBlurredShadows) { + ctx.shadowOffsetX = shift; + ctx.shadowOffsetY = shift; + ctx.shadowBlur = this.edge; + ctx.shadowColor = this.color.darker(80).toString(); + } + + // top edge: straight line + gradient = ctx.createLinearGradient( + 0, + 0, + 0, + this.edge + ); + gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.cachedClr); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(r - shift, shift); + ctx.lineTo(w - r + shift, shift); + ctx.stroke(); + + // top edge: left corner + gradient = ctx.createRadialGradient( + r, + r, + r - this.edge, + r, + r, + r + ); + gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.cachedClrDark); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.arc( + r, + r, + r - shift, + radians(180), + radians(270), + false + ); + ctx.stroke(); + + // left edge: straight vertical line + gradient = ctx.createLinearGradient(0, 0, this.edge, 0); + gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.cachedClr); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(shift, r); + ctx.lineTo(shift, h - r); + ctx.stroke(); + + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 0; + ctx.shadowBlur = 0; + + // bottom edge: right corner + gradient = ctx.createRadialGradient( + w - r, + h - r, + r - this.edge, + w - r, + h - r, + r + ); + gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.cachedClrBright); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.arc( + w - r, + h - r, + r - shift, + radians(0), + radians(90), + false + ); + ctx.stroke(); + + // bottom edge: straight line + gradient = ctx.createLinearGradient( + 0, + h - this.edge, + 0, + h + ); + gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.cachedClrBright); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(r - shift, h - shift); + ctx.lineTo(w - r + shift, h - shift); + ctx.stroke(); + + // right edge: straight vertical line + gradient = ctx.createLinearGradient(w - this.edge, 0, w, 0); + gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.cachedClrBright); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(w - shift, r + shift); + ctx.lineTo(w - shift, h - r); + ctx.stroke(); +}; + +RingReporterSlotMorph.prototype.outlinePathDiamond = function (ctx, offset) { + var ox = offset.x, + oy = offset.y, + w = this.width(), + h = this.height(), + h2 = Math.floor(h / 2), + r = Math.min(this.rounding, h2); + + ctx.moveTo(ox + this.edge, h2 + oy); + ctx.lineTo(r + this.edge + ox, this.edge + oy); + ctx.lineTo(w - r - this.edge + ox, this.edge + oy); + ctx.lineTo(w - this.edge + ox, h2 + oy); + ctx.lineTo(w - r - this.edge + ox, h - this.edge + oy); + ctx.lineTo(r + this.edge + ox, h - this.edge + oy); + ctx.lineTo(ox + this.edge, h2 + oy); +}; + +RingReporterSlotMorph.prototype.drawEdgesDiamond = function (ctx) { + var w = this.width(), + h = this.height(), + h2 = Math.floor(h / 2), + r = Math.min(this.rounding, h2), + shift = this.edge / 2, + gradient; + + // add 3D-Effect: + ctx.lineWidth = this.edge; + ctx.lineJoin = 'round'; + ctx.lineCap = 'round'; + + // half-tone edges + // bottom left corner + ctx.strokeStyle = this.cachedClr; + ctx.beginPath(); + ctx.moveTo(shift, h2); + ctx.lineTo(r, h - shift); + ctx.stroke(); + + // top right corner + ctx.strokeStyle = this.cachedClr; + ctx.beginPath(); + ctx.moveTo(w - shift, h2); + ctx.lineTo(w - r, shift); + ctx.stroke(); + + // normal gradient edges + // top edge: left corner + + if (useBlurredShadows) { + ctx.shadowOffsetX = shift; + ctx.shadowOffsetY = shift; + ctx.shadowBlur = this.edge; + ctx.shadowColor = this.color.darker(80).toString(); + } + + gradient = ctx.createLinearGradient( + 0, + 0, + r, + 0 + ); + gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.cachedClr); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(shift, h2); + ctx.lineTo(r, shift); + ctx.stroke(); + + // top edge: straight line + gradient = ctx.createLinearGradient( + 0, + 0, + 0, + this.edge + ); + gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(0, this.cachedClr); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(r, shift); + ctx.lineTo(w - r, shift); + ctx.stroke(); + + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 0; + ctx.shadowBlur = 0; + + // bottom edge: right corner + gradient = ctx.createLinearGradient( + w - r, + 0, + w, + 0 + ); + gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.cachedClrBright); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(w - r, h - shift); + ctx.lineTo(w - shift, h2); + ctx.stroke(); + + // bottom edge: straight line + gradient = ctx.createLinearGradient( + 0, + h - this.edge, + 0, + h + ); + gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.cachedClrBright); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(r + shift, h - shift); + ctx.lineTo(w - r - shift, h - shift); + ctx.stroke(); +}; + +// CommentMorph ////////////////////////////////////////////////////////// + +/* + I am an editable, multi-line non-scrolling text window. I can be collapsed + to a single abbreviated line or expanded to full. My width can be adjusted + by the user, by height is determined by the size of my text body. I can be + either placed in a scripting area or "stuck" to a block. +*/ + +// CommentMorph inherits from BoxMorph: + +CommentMorph.prototype = new BoxMorph(); +CommentMorph.prototype.constructor = CommentMorph; +CommentMorph.uber = BoxMorph.prototype; + +// CommentMorph preferences settings (pseudo-inherited from SyntaxElement): + +CommentMorph.prototype.refreshScale = function () { + CommentMorph.prototype.fontSize = SyntaxElementMorph.prototype.fontSize; + CommentMorph.prototype.padding = 5 * SyntaxElementMorph.prototype.scale; + CommentMorph.prototype.rounding = 8 * SyntaxElementMorph.prototype.scale; +}; + +CommentMorph.prototype.refreshScale(); + +// CommentMorph instance creation: + +function CommentMorph(contents) { + this.init(contents); +} + +CommentMorph.prototype.init = function (contents) { + var scale = SyntaxElementMorph.prototype.scale; + + this.block = null; // optional anchor block + this.stickyOffset = null; // not to be persisted + this.isCollapsed = false; + this.titleBar = new BoxMorph( + this.rounding, + scale, + new Color(255, 255, 180) + ); + this.titleBar.color = new Color(255, 255, 180); + this.titleBar.setHeight(fontHeight(this.fontSize) + this.padding); + this.title = null; + this.arrow = new ArrowMorph( + 'down', + this.fontSize + ); + this.arrow.mouseClickLeft = () => this.toggleExpand(); + this.contents = new TextMorph( + contents || localize('add comment here...'), + this.fontSize + ); + this.contents.isEditable = true; + this.contents.enableSelecting(); + this.contents.maxWidth = 90 * scale; + this.contents.fixLayout(); + this.handle = new HandleMorph( + this.contents, + 80, + this.fontSize * 2, + -2, + -2 + ); + this.handle.setExtent(new Point(11 * scale, 11 * scale)); + this.anchor = null; + + CommentMorph.uber.init.call( + this, + this.rounding, + scale, + new Color(255, 255, 180) + ); + this.color = new Color(255, 255, 220); + this.isDraggable = true; + this.add(this.titleBar); + this.add(this.arrow); + this.add(this.contents); + this.add(this.handle); + + this.fixLayout(); +}; + +// CommentMorph ops: + +CommentMorph.prototype.fullCopy = function () { + var cpy = new CommentMorph(this.contents.text); + cpy.isCollapsed = this.isCollapsed; + cpy.setTextWidth(this.textWidth()); + if (this.selectionID) { // for copy on write + cpy.selectionID = true; + } + return cpy; +}; + +CommentMorph.prototype.setTextWidth = function (pixels) { + this.contents.maxWidth = pixels; + this.contents.fixLayout(); + this.fixLayout(); +}; + +CommentMorph.prototype.textWidth = function () { + return this.contents.maxWidth; +}; + +CommentMorph.prototype.text = function () { + return this.contents.text; +}; + +CommentMorph.prototype.toggleExpand = function () { + var scripts = this.parentThatIsA(ScriptsMorph); + this.isCollapsed = !this.isCollapsed; + this.fixLayout(); + this.align(); + if (!this.isCollapsed) { + this.comeToFront(); + } + if (scripts) { + scripts.scriptTarget().recordUserEdit( + 'scripts', + 'comment', + this.isCollapsed ? 'collapse' : 'expand' + ); + } +}; + +CommentMorph.prototype.comeToFront = function () { + if (this.parent) { + this.parent.add(this); + this.changed(); + } +}; + +// CommentMorph events: + +CommentMorph.prototype.mouseClickLeft = function () { + this.comeToFront(); +}; + +CommentMorph.prototype.reactToEdit = function () { + var scripts = this.parentThatIsA(ScriptsMorph); + if (scripts) { + scripts.scriptTarget().recordUserEdit( + 'scripts', + 'comment', + 'edit' + ); + } +}; + +// CommentMorph layout: + +CommentMorph.prototype.layoutChanged = function () { + // react to a change of the contents area + this.fixLayout(); + this.align(); + this.comeToFront(); +}; + +CommentMorph.prototype.fixLayout = function () { + var label, + tw = this.contents.width() + 2 * this.padding; + + if (this.title) { + this.title.destroy(); + this.title = null; + } + if (this.isCollapsed) { + this.contents.hide(); + this.title = new FrameMorph(); + this.title.alpha = 0; + this.title.acceptsDrops = false; + label = new StringMorph( + this.contents.text, + this.fontSize, + null, // style (sans-serif) + true // bold + ); + label.rootForGrab = () => this; + this.title.add(label); + this.title.setHeight(label.height()); + this.title.setWidth( + tw - this.arrow.width() - this.padding * 2 - this.rounding + ); + this.add(this.title); + } else { + this.contents.show(); + } + this.titleBar.setWidth(tw); + this.contents.setLeft(this.titleBar.left() + this.padding); + this.contents.setTop(this.titleBar.bottom() + this.padding); + this.arrow.direction = this.isCollapsed ? 'right' : 'down'; + this.arrow.rerender(); + this.arrow.setCenter(this.titleBar.center()); + this.arrow.setLeft(this.titleBar.left() + this.padding); + if (this.title) { + this.title.setPosition( + this.arrow.topRight().add(new Point(this.padding, 0)) + ); + } + this.changed(); + this.bounds.setHeight( + this.titleBar.height() + + (this.isCollapsed ? 0 : + this.padding + + this.contents.height() + + this.padding) + ); + this.bounds.setWidth(this.titleBar.width()); + this.rerender(); + this.handle.fixLayout(); +}; + +// CommentMorph menu: + +CommentMorph.prototype.userMenu = function () { + var menu = new MenuMorph(this); + + menu.addItem( + "duplicate", + () => { + var dup = this.fullCopy(), + ide = this.parentThatIsA(IDE_Morph), + blockEditor = this.parentThatIsA(BlockEditorMorph), + scripts = this.parentThatIsA(ScriptsMorph), + world = this.world(); + dup.pickUp(world); + // register the drop-origin, so the comment can + // slide back to its former situation if dropped + // somewhere where it gets rejected + if (!ide && blockEditor) { + ide = blockEditor.target.parentThatIsA(IDE_Morph); + } + if (ide) { + world.hand.grabOrigin = { + origin: ide.palette, + position: ide.palette.center() + }; + } + if (scripts) { + scripts.scriptTarget().recordUserEdit( + 'scripts', + 'comment', + 'duplicate' + ); + } + }, + 'make a copy\nand pick it up' + ); + menu.addItem("delete", 'userDestroy'); + menu.addItem( + "comment pic...", + () => { + var ide = this.parentThatIsA(IDE_Morph) || + this.parentThatIsA(BlockEditorMorph) + .target.parentThatIsA(IDE_Morph); + ide.saveCanvasAs( + this.fullImage(), + (ide.projectName || localize('untitled')) + ' ' + + localize('comment pic') + ); + }, + 'save a picture\nof this comment' + ); + return menu; +}; + +CommentMorph.prototype.userDestroy = function () { + var scripts = this.parentThatIsA(ScriptsMorph); + if (scripts) { + scripts.scriptTarget().recordUserEdit( + 'scripts', + 'comment', + 'delete' + ); + } + this.selectForEdit().destroy(); // enable copy-on-edit +}; + +// CommentMorph hiding and showing: + +/* + override the inherited behavior to recursively hide/show all + children, so that my instances get restored correctly when + switching back out of app mode. +*/ + +CommentMorph.prototype.hide = function () { + this.isVisible = false; + this.changed(); +}; + +CommentMorph.prototype.show = function () { + this.isVisible = true; + this.changed(); +}; + +// CommentMorph dragging & dropping + +CommentMorph.prototype.prepareToBeGrabbed = function (hand) { + // disassociate from the block I'm posted to + var scripts = this.parentThatIsA(ScriptsMorph); + if (scripts) { + scripts.scriptTarget().recordUserEdit( + 'scripts', + 'comment', + 'grab' + ); + } + if (this.block) { + this.block.comment = null; + this.block = null; + } + if (this.anchor) { + this.anchor.destroy(); + this.anchor = null; + } +}; + +CommentMorph.prototype.justDropped = function (hand) { + var scripts = this.parentThatIsA(ScriptsMorph); + if (scripts) { + scripts.scriptTarget().recordUserEdit( + 'scripts', + 'comment', + 'drop' + ); + } +}; + +CommentMorph.prototype.selectForEdit = + SyntaxElementMorph.prototype.selectForEdit; + +CommentMorph.prototype.snap = function (hand) { + // passing the hand is optional (for when blocks are dragged & dropped) + var scripts = this.parent, + target; + + if (!(scripts instanceof ScriptsMorph)) { + return null; + } + scripts.clearDropInfo(); + target = scripts.closestBlock(this, hand); + if (target !== null) { + target.comment = this; + this.block = target; + if (this.snapSound) { + this.snapSound.play(); + } + scripts.lastDropTarget = {element: target}; + scripts.scriptTarget().recordUserEdit( + 'scripts', + 'comment', + 'snap', + this.block.abstractBlockSpec() + ); + } + this.align(); + scripts.lastDroppedBlock = this; + if (hand) { + scripts.recordDrop(hand.grabOrigin); + } + +}; + +// CommentMorph sticking to blocks + +CommentMorph.prototype.align = function (topBlock, ignoreLayer) { + if (this.block) { + var top = topBlock || this.block.topBlock(), + affectedBlocks, + tp, + bottom, + rightMost, + scripts = top.parentThatIsA(ScriptsMorph); + this.setTop(this.block.top() + this.block.corner); + tp = this.top(); + bottom = this.bottom(); + affectedBlocks = top.allChildren().filter(child => + child instanceof BlockMorph && + child.bottom() > tp && + child.top() < bottom + ); + rightMost = Math.max.apply( + null, + affectedBlocks.map(block => block.right()) + ); + + this.setLeft(rightMost + 5); + if (!ignoreLayer && scripts) { + scripts.addBack(this); // push to back and show + } + + if (!this.anchor) { + this.anchor = new Morph(); + this.anchor.color = this.titleBar.color; + } + this.anchor.setPosition(new Point( + this.block.right(), + this.top() + this.edge + )); + this.anchor.bounds.corner = new Point( + this.left(), + this.top() + this.edge + 1 + ); + this.anchor.rerender(); + this.addBack(this.anchor); + } +}; + +CommentMorph.prototype.startFollowing = function (topBlock, world) { + this.align(topBlock); + world.add(this); + this.addShadow(); + this.stickyOffset = this.position().subtract(this.block.position()); + this.step = () => { + if (!this.block) { // kludge - only needed for "redo" + this.stopFollowing(); + return; + } + this.setPosition(this.block.position().add(this.stickyOffset)); + }; +}; + +CommentMorph.prototype.stopFollowing = function () { + this.removeShadow(); + delete this.step; +}; + +CommentMorph.prototype.destroy = function () { + if (this.block) { + this.block.comment = null; + } + CommentMorph.uber.destroy.call(this); +}; + +CommentMorph.prototype.stackHeight = function () { + return this.height(); +}; + +// ScriptFocusMorph ////////////////////////////////////////////////////////// + +/* + I offer keyboard navigation for syntax elements, blocks and scripts: + + activate: + - shift + click on a scripting pane's background + - shift + click on any block + - shift + enter in the IDE's edit mode + + stop editing: + - left-click on scripting pane's background + - esc + + navigate among scripts: + - tab: next script + - backtab (shift + tab): last script + + start editing a new script: + - shift + enter + + navigate among commands within a script: + - down arrow: next command + - up arrow: last command + + navigate among all elements within a script: + - right arrow: next element (block or input) + - left arrow: last element + + move the currently edited script (stack of blocks): + - shift + arrow keys (left, right, up, down) + + editing scripts: + + - backspace: + * delete currently focused reporter + * delete command above current insertion mark (blinking) + * collapse currently focused variadic input by one element + + - enter: + * edit currently focused input slot + * expand currently focused variadic input by one element + + - space: + * activate currently focused input slot's pull-down menu, if any + * show a menu of reachable variables for the focused input or reporter + + - any other key: + start searching for insertable matching blocks + + - in menus triggered by this feature: + * navigate with up / down arrow keys + * trigger selection with enter + * cancel menu with esc + + - in the search bar triggered b this feature: + * keep typing / deleting to narrow and update matches + * navigate among shown matches with up / down arrow keys + * insert selected match at the focus' position with enter + * cancel searching and inserting with esc + + running the currently edited script: + * shift+ctrl+enter simulates clicking the edited script with the mouse +*/ + +// ScriptFocusMorph inherits from BoxMorph: + +ScriptFocusMorph.prototype = new BoxMorph(); +ScriptFocusMorph.prototype.constructor = ScriptFocusMorph; +ScriptFocusMorph.uber = BoxMorph.prototype; + +// ScriptFocusMorph instance creation: + +function ScriptFocusMorph(editor, initialElement, position) { + this.init(editor, initialElement, position); +} + +ScriptFocusMorph.prototype.init = function ( + editor, + initialElement, + position +) { + this.editor = editor; // a ScriptsMorph + this.element = initialElement; + this.atEnd = false; + ScriptFocusMorph.uber.init.call(this); + if (this.element instanceof ScriptsMorph) { + this.setPosition(position); + } +}; + +// ScriptFocusMorph keyboard focus: + +ScriptFocusMorph.prototype.getFocus = function (world) { + if (!world) {world = this.world(); } + if (world && world.keyboardFocus !== this) { + world.stopEditing(); + } + world.keyboardFocus = this; + this.fixLayout(); + this.editor.updateToolbar(); +}; + +// ScriptFocusMorph layout: + +ScriptFocusMorph.prototype.fixLayout = function () { + this.changed(); + if (this.element instanceof CommandBlockMorph || + this.element instanceof CommandSlotMorph || + this.element instanceof ScriptsMorph) { + this.manifestStatement(); + } else { + this.manifestExpression(); + } + this.editor.add(this); // come to front + this.scrollIntoView(); + this.changed(); +}; + +ScriptFocusMorph.prototype.manifestStatement = function () { + var newScript = this.element instanceof ScriptsMorph, + y = this.element.top(); + this.border = 0; + this.edge = 0; + this.alpha = 1; + this.color = this.editor.feedbackColor; + this.bounds.setExtent(new Point( + newScript ? + SyntaxElementMorph.prototype.hatWidth : this.element.width(), + Math.max( + SyntaxElementMorph.prototype.corner, + SyntaxElementMorph.prototype.feedbackMinHeight + ) + )); + if (this.element instanceof CommandSlotMorph) { + y += SyntaxElementMorph.prototype.corner; + } else if (this.atEnd) { + y = this.element.bottom(); + } + if (!newScript) { + this.setPosition(new Point( + this.element.left(), + y + )); + } + this.fps = 2; + this.show(); + this.step = function () { + this.toggleVisibility(); + }; +}; + +ScriptFocusMorph.prototype.manifestExpression = function () { + this.edge = SyntaxElementMorph.prototype.rounding; + this.border = Math.max( + SyntaxElementMorph.prototype.edge, + 3 + ); + this.color = this.editor.feedbackColor.copy(); + this.color.a = 0.5; + this.borderColor = this.editor.feedbackColor; + + this.bounds = this.element.fullBounds() + .expandBy(Math.max( + SyntaxElementMorph.prototype.edge * 2, + SyntaxElementMorph.prototype.reporterDropFeedbackPadding + )); + this.rerender(); + delete this.fps; + delete this.step; + this.show(); +}; + +// ScriptFocusMorph editing + +ScriptFocusMorph.prototype.trigger = function () { + var current = this.element, + i; + if (current instanceof MultiArgMorph) { + for (i = 0; i < current.groupInputs; i += 1) { + if (current.arrows().children[1].isVisible) { + current.addInput(); + this.fixLayout(); + } + } + return; + } + if (current.parent instanceof TemplateSlotMorph) { + current.mouseClickLeft(); + return; + } + if (current instanceof BooleanSlotMorph) { + current.toggleValue(); + return; + } + if (current instanceof InputSlotMorph) { + if (!current.isReadOnly) { + delete this.fps; + delete this.step; + this.hide(); + this.world().onNextStep = () => { + current.contents().edit(); + current.contents().selectAll(); + }; + } else if (current.choices) { + current.dropDownMenu(true); + delete this.fps; + delete this.step; + this.hide(); + } + } +}; + +ScriptFocusMorph.prototype.menu = function () { + var current = this.element; + if (current instanceof InputSlotMorph && current.choices) { + current.dropDownMenu(true); + delete this.fps; + delete this.step; + this.hide(); + } else { + this.insertVariableGetter(); + } +}; + +ScriptFocusMorph.prototype.deleteLastElement = function () { + var current = this.element, + i; + if (current.parent instanceof ScriptsMorph) { + if (this.atEnd || current instanceof ReporterBlockMorph) { + current.destroy(); + this.element = this.editor; + this.atEnd = false; + } + } else if (current instanceof MultiArgMorph) { + for (i = 0; i < current.groupInputs; i += 1) { + if (current.arrows().children[0].isVisible) { + current.removeInput(); + } + } + } else if (current instanceof BooleanSlotMorph) { + if (!current.isStatic) { + current.setContents(null); + } + } else if (current instanceof ReporterBlockMorph) { + if (!current.isTemplate) { + this.lastElement(); + current.prepareToBeGrabbed(); + current.destroy(); + } + } else if (current instanceof CommandBlockMorph) { + if (this.atEnd) { + this.element = current.parent; + current.userDestroy(); + } else { + if (current.parent instanceof CommandBlockMorph) { + current.parent.userDestroy(); + } + } + } + this.editor.adjustBounds(); + this.fixLayout(); +}; + +ScriptFocusMorph.prototype.insertBlock = function (block) { + // insert the block after a short gliding animation + this.world().add(block); + block.glideTo( + this.position(), + null, + null, + () => this.fillInBlock(block) + ); +}; + +ScriptFocusMorph.prototype.fillInBlock = function (block) { + var pb, stage, ide, rcvr; + block.isTemplate = false; + block.isDraggable = true; + + if (block.snapSound) { + block.snapSound.play(); + } + + if (this.element instanceof ScriptsMorph) { + this.editor.add(block); + this.element = block; + if (block instanceof CommandBlockMorph) { + block.setLeft(this.left()); + if (block.isStop()) { + block.setTop(this.top()); + } else { + block.setBottom(this.top()); + this.atEnd = true; + } + } else { + block.setCenter(this.center()); + block.setLeft(this.left()); + } + } else if (this.element instanceof CommandBlockMorph) { + if (this.atEnd) { + this.element.nextBlock(block); + this.element = block; + this.fixLayout(); + } else { + // to be done: special case if block.isStop() + pb = this.element.parent; + if (pb instanceof ScriptsMorph) { // top block + block.setLeft(this.element.left()); + block.setBottom(this.element.top() + this.element.corner); + this.editor.add(block); + block.nextBlock(this.element); + this.fixLayout(); + } else if (pb instanceof CommandSlotMorph) { + pb.nestedBlock(block); + } else if (pb instanceof RingReporterSlotMorph) { + block.nextBlock(pb.nestedBlock()); + pb.add(block); + pb.fixLayout(); + } else if (pb instanceof CommandBlockMorph) { + pb.nextBlock(block); + } + } + } else if (this.element instanceof CommandSlotMorph) { + // to be done: special case if block.isStop() + this.element.nestedBlock(block); + this.element = block; + this.atEnd = true; + } else { + pb = this.element.parent; + if (pb instanceof ScriptsMorph) { + this.editor.add(block); + block.setPosition(this.element.position()); + this.element.destroy(); + } else { + pb.replaceInput(this.element, block); + } + this.element = block; + } + block.fixBlockColor(); + this.editor.adjustBounds(); + // block.scrollIntoView(); + this.fixLayout(); + + // register generic hat blocks + if (block.selector === 'receiveCondition') { + rcvr = this.editor.scriptTarget(); + if (rcvr) { + stage = rcvr.parentThatIsA(StageMorph); + if (stage) { + stage.enableCustomHatBlocks = true; + stage.threads.pauseCustomHatBlocks = false; + ide = stage.parentThatIsA(IDE_Morph); + if (ide) { + ide.controlBar.stopButton.refresh(); + } + } + } + } + + // experimental: if the inserted block has inputs, go to the first one + if (block.inputs && block.inputs().length) { + this.element = block; + this.atEnd = false; + this.nextElement(); + } +}; + +ScriptFocusMorph.prototype.insertVariableGetter = function () { + var types = this.blockTypes(), + vars, + menu = new MenuMorph(); + if (!types || !contains(types, 'reporter')) { + return; + } + vars = InputSlotMorph.prototype.getVarNamesDict.call(this.element); + Object.keys(vars).forEach(vName => { + var block = SpriteMorph.prototype.variableBlock(vName); + block.addShadow(new Point(3, 3)); + menu.addItem( + block, + () => { + block.removeShadow(); + this.insertBlock(block); + } + ); + }); + if (menu.items.length > 0) { + menu.popup(this.world(), this.element.bottomLeft()); + menu.getFocus(); + } +}; + +ScriptFocusMorph.prototype.stopEditing = function () { + this.editor.focus = null; + this.editor.updateToolbar(); + this.world().keyboardFocus = null; + this.destroy(); +}; + +// ScriptFocusMorph navigation + +ScriptFocusMorph.prototype.lastElement = function () { + var items = this.items(), + idx; + if (!items.length) { + this.shiftScript(new Point(-50, 0)); + return; + } + if (this.atEnd) { + this.element = items[items.length - 1]; + this.atEnd = false; + } else { + idx = items.indexOf(this.element) - 1; + if (idx < 0) {idx = items.length - 1; } + this.element = items[idx]; + } + if (this.element instanceof CommandSlotMorph && + this.element.nestedBlock()) { + this.lastElement(); + } else if (this.element instanceof HatBlockMorph) { + if (items.length > 1) { + this.lastElement(); + } else { + this.atEnd = true; + } + } + this.fixLayout(); +}; + +ScriptFocusMorph.prototype.nextElement = function () { + var items = this.items(), idx, nb; + if (!items.length) { + this.shiftScript(new Point(50, 0)); + return; + } + idx = items.indexOf(this.element) + 1; + if (idx >= items.length) { + idx = 0; + } + this.atEnd = false; + this.element = items[idx]; + if (this.element instanceof CommandSlotMorph) { + nb = this.element.nestedBlock(); + if (nb) {this.element = nb; } + } else if (this.element instanceof HatBlockMorph) { + if (items.length === 1) { + this.atEnd = true; + } else { + this.nextElement(); + } + } + this.fixLayout(); +}; + +ScriptFocusMorph.prototype.lastCommand = function () { + var cm = this.element.parentThatIsA(CommandBlockMorph), + pb; + if (!cm) { + if (this.element instanceof ScriptsMorph) { + this.shiftScript(new Point(0, -50)); + } + return; + } + if (this.element instanceof CommandBlockMorph) { + if (this.atEnd) { + this.atEnd = false; + } else { + pb = cm.parent.parentThatIsA(CommandBlockMorph); + if (pb) { + this.element = pb; + } else { + pb = cm.topBlock().bottomBlock(); + if (pb) { + this.element = pb; + this.atEnd = true; + } + } + } + } else { + this.element = cm; + this.atEnd = false; + } + if (this.element instanceof HatBlockMorph && !this.atEnd) { + this.lastCommand(); + } + this.fixLayout(); +}; + +ScriptFocusMorph.prototype.nextCommand = function () { + var cm = this.element, + tb, + nb, + cs; + if (cm instanceof ScriptsMorph) { + this.shiftScript(new Point(0, 50)); + return; + } + while (!(cm instanceof CommandBlockMorph)) { + cm = cm.parent; + if (cm instanceof ScriptsMorph) { + return; + } + } + if (this.atEnd) { + cs = cm.parentThatIsA(CommandSlotMorph); + if (cs) { + this.element = cs.parentThatIsA(CommandBlockMorph); + this.atEnd = false; + this.nextCommand(); + } else { + tb = cm.topBlock().parentThatIsA(CommandBlockMorph); + if (tb) { + this.element = tb; + this.atEnd = false; + if (this.element instanceof HatBlockMorph) { + this.nextCommand(); + } + } + } + } else { + nb = cm.nextBlock(); + if (nb) { + this.element = nb; + } else { + this.element = cm; + this.atEnd = true; + } + } + this.fixLayout(); +}; + +ScriptFocusMorph.prototype.nextScript = function () { + var scripts = this.sortedScripts(), + idx; + if (scripts.length < 1) {return; } + if (this.element instanceof ScriptsMorph) { + this.element = scripts[0]; + } + idx = scripts.indexOf(this.element.topBlock()) + 1; + if (idx >= scripts.length) {idx = 0; } + this.element = scripts[idx]; + this.element.scrollIntoView(); + this.atEnd = false; + if (this.element instanceof HatBlockMorph) { + return this.nextElement(); + } + this.fixLayout(); +}; + +ScriptFocusMorph.prototype.lastScript = function () { + var scripts = this.sortedScripts(), + idx; + if (scripts.length < 1) {return; } + if (this.element instanceof ScriptsMorph) { + this.element = scripts[0]; + } + idx = scripts.indexOf(this.element.topBlock()) - 1; + if (idx < 0) {idx = scripts.length - 1; } + this.element = scripts[idx]; + this.element.scrollIntoView(); + this.atEnd = false; + if (this.element instanceof HatBlockMorph) { + return this.nextElement(); + } + this.fixLayout(); +}; + +ScriptFocusMorph.prototype.shiftScript = function (deltaPoint) { + var tb; + if (this.element instanceof ScriptsMorph) { + this.moveBy(deltaPoint); + } else { + tb = this.element.topBlock(); + if (tb && !(tb instanceof PrototypeHatBlockMorph)) { + tb.moveBy(deltaPoint); + } + } + this.editor.adjustBounds(); + this.fixLayout(); +}; + +ScriptFocusMorph.prototype.newScript = function () { + var pos = this.position(); + if (!(this.element instanceof ScriptsMorph)) { + pos = this.element.topBlock().fullBounds().bottomLeft().add( + new Point(0, 50) + ); + } + this.setPosition(pos); + this.element = this.editor; + this.editor.adjustBounds(); + this.fixLayout(); +}; + +ScriptFocusMorph.prototype.runScript = function () { + if (this.element instanceof ScriptsMorph) {return; } + this.element.topBlock().mouseClickLeft(); +}; + +ScriptFocusMorph.prototype.items = function () { + if (this.element instanceof ScriptsMorph) {return []; } + var script = this.element.topBlock(); + return script.allChildren().filter(each => + each instanceof SyntaxElementMorph && + !(each instanceof TemplateSlotMorph) && + (!each.isStatic || + each.choices || + each instanceof BooleanSlotMorph || + each instanceof RingMorph || + each instanceof MultiArgMorph || + each instanceof CommandSlotMorph + ) + ); +}; + +ScriptFocusMorph.prototype.sortedScripts = function () { + var scripts = this.editor.children.filter(each => + each instanceof BlockMorph + ); + scripts.sort((a, b) => + // make sure the prototype hat block always stays on top + a instanceof PrototypeHatBlockMorph ? 0 : a.top() - b.top() + ); + return scripts; +}; + +// ScriptFocusMorph undo / redo + +ScriptFocusMorph.prototype.undrop = function () { + this.editor.undrop(); +}; + +ScriptFocusMorph.prototype.redrop = function () { + this.editor.redrop(); +}; + +// ScriptFocusMorph block types + +ScriptFocusMorph.prototype.blockTypes = function () { + // answer an array of possible block types that fit into + // the current situation, NULL if no block can be inserted + + if (this.element.isTemplate) {return null; } + if (this.element instanceof ScriptsMorph) { + return ['hat', 'command', 'reporter', 'predicate', 'ring']; + } + if (this.element instanceof HatBlockMorph || + this.element instanceof CommandSlotMorph) { + return ['command']; + } + if (this.element instanceof CommandBlockMorph) { + if (this.atEnd && this.element.isStop()) { + return null; + } + if (this.element.parent instanceof ScriptsMorph) { + return ['hat', 'command']; + } + return ['command']; + } + if (this.element instanceof ReporterBlockMorph) { + if (this.element.getSlotSpec() === '%n') { + return ['reporter']; + } + return ['reporter', 'predicate', 'ring']; + } + if (this.element.getSpec() === '%n') { + return ['reporter']; + } + if (this.element.isStatic) { + return null; + } + return ['reporter', 'predicate', 'ring']; +}; + + +// ScriptFocusMorph keyboard events + +ScriptFocusMorph.prototype.processKeyDown = function (event) { + this.processKeyEvent( + event, + this.reactToKeyEvent + ); +}; + +ScriptFocusMorph.prototype.processKeyUp = function (event) { + nop(event); +}; + +ScriptFocusMorph.prototype.processKeyPress = function (event) { + nop(event); +}; + + +ScriptFocusMorph.prototype.processKeyEvent = function (event, action) { + var keyName, ctrl, shift; + + //console.log(event.keyCode); + this.world().hand.destroyTemporaries(); // remove result bubbles, if any + switch (event.keyCode) { + case 8: + keyName = 'backspace'; + break; + case 9: + keyName = 'tab'; + break; + case 13: + keyName = 'enter'; + break; + case 16: + case 17: + case 18: + return; + case 27: + keyName = 'esc'; + break; + case 32: + keyName = 'space'; + break; + case 37: + keyName = 'left arrow'; + break; + case 39: + keyName = 'right arrow'; + break; + case 38: + keyName = 'up arrow'; + break; + case 40: + keyName = 'down arrow'; + break; + default: + keyName = String.fromCharCode(event.keyCode || event.charCode); + } + ctrl = (event.ctrlKey || event.metaKey) ? 'ctrl ' : ''; + shift = event.shiftKey ? 'shift ' : ''; + keyName = ctrl + shift + keyName; + action.call(this, keyName); +}; + +ScriptFocusMorph.prototype.reactToKeyEvent = function (key) { + var evt = key.toLowerCase(), + shift = 50, + types, + vNames; + + // console.log(evt); + switch (evt) { + case 'esc': + return this.stopEditing(); + case 'enter': + return this.trigger(); + case 'shift enter': + return this.newScript(); + case 'ctrl shift enter': + return this.runScript(); + case 'space': + return this.menu(); + case 'left arrow': + return this.lastElement(); + case 'shift left arrow': + return this.shiftScript(new Point(-shift, 0)); + case 'right arrow': + return this.nextElement(); + case 'shift right arrow': + return this.shiftScript(new Point(shift, 0)); + case 'up arrow': + return this.lastCommand(); + case 'shift up arrow': + return this.shiftScript(new Point(0, -shift)); + case 'down arrow': + return this.nextCommand(); + case 'shift down arrow': + return this.shiftScript(new Point(0, shift)); + case 'tab': + return this.nextScript(); + case 'shift tab': + return this.lastScript(); + case 'backspace': + return this.deleteLastElement(); + case 'ctrl z': + return this.undrop(); + case 'ctrl y': + case 'ctrl shift z': + return this.redrop(); + case 'ctrl [': // ignore the first press of the Mac cmd key + return; + default: + types = this.blockTypes(); + if (!(this.element instanceof ScriptsMorph) && + types && contains(types, 'reporter')) { + vNames = Object.keys(this.element.getVarNamesDict()); + } + if (types) { + delete this.fps; + delete this.step; + this.show(); + this.editor.scriptTarget().searchBlocks( + key, + types, + vNames, + this + ); + } + } +}; + + +/* +// register examples with the World demo menu +// comment out to shave off a millisecond loading speed ;-) + +(function () { + var h, b, c, ci, cb, cm, cd, co, cl, cu, cs, cmd, rings, rc, scripts; + // SyntaxElementMorph.prototype.setScale(2.5); + + h = new HatBlockMorph(); + h.setSpec('When $greenflag pressed'); + + b = new ReporterBlockMorph(true); + b.setSpec('%bool'); + + c = new CommandBlockMorph(); + c.setSpec('this is a test $globe'); + + ci = new CommandBlockMorph(); + ci.setSpec('block with input %s unit %mult%n number'); + + cb = new CommandBlockMorph(); + cb.setSpec('bool %b ?'); + + cd = new CommandBlockMorph(); + cd.setSpec('direction %dir degrees'); + + co = new CommandBlockMorph(); + co.setSpec('object %obj'); + + cl = new CommandBlockMorph(); + cl.setSpec('list %l'); + + cu = new CommandBlockMorph(); + cu.setSpec('list %upvar'); + + cs = new CommandBlockMorph(); + cs.setSpec('control %b %ca'); + + cmd = new CommandBlockMorph(); + cmd.setSpec('command %cmdRing'); + + rings = new CommandBlockMorph(); + rings.setSpec('reporter %repRing predicate %predRing'); + + rc = new ReporterBlockMorph(); + rc.setSpec('color %clr'); + + scripts = new ScriptsMorph(); + + BlockMorph.prototype.addToDemoMenu([ + 'Syntax', + [ + [h, 'hat'], + [b, 'predicate'], + [c, 'with label text'], + [ci, 'editable input slots'], + [cb, 'Boolean slot'], + [cm, 'menu input'], + [cd, 'direction input'], + [co, 'object input'], + [cl, 'list input'], + [cu, 'upvar input'], + [cs, 'loop input'], + [cmd, 'cmd ring input'], + [rings, 'reporter rings input'], + [rc, 'color input'], + [scripts, 'scripts'] + ] + ]); +})(); +*/ From 422cbc4964560fd568c73f023bf313bd0f2cf881 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:36:33 +0000 Subject: [PATCH 066/132] fix --- src/blocks.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/blocks.js b/src/blocks.js index 9d1ae4fc2c..9e6b9a7b2e 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -10774,6 +10774,8 @@ InputSlotMorph.prototype.init = function ( choiceDict, isReadOnly ) { + + this.alpha = 0 var contents = new InputSlotStringMorph(''), arrow = new ArrowMorph( 'down', @@ -12139,6 +12141,7 @@ InputSlotMorph.prototype.unflash = function () { InputSlotMorph.prototype.render = function (ctx) { var borderColor, r; this.alpha = 0 + this.color = this.parentThatIsA(BlockMorph).color // initialize my surface property if (this.cachedNormalColor) { // if flashing borderColor = this.color; From 6c8712298bfda54bc757ebe90098c4161a2d088d Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:40:08 +0000 Subject: [PATCH 067/132] fix outline glitch(visual) --- src/blocks.js | 63 --------------------------------------------------- 1 file changed, 63 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 9e6b9a7b2e..76cd4b6a9b 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -12142,69 +12142,6 @@ InputSlotMorph.prototype.render = function (ctx) { var borderColor, r; this.alpha = 0 this.color = this.parentThatIsA(BlockMorph).color - // initialize my surface property - if (this.cachedNormalColor) { // if flashing - borderColor = this.color; - } else if (this.parent) { - borderColor = this.parent.color; - } else { - borderColor = new Color(120, 120, 120); - } - ctx.fillStyle = this.color.toString(); - if (this.isReadOnly && !this.cachedNormalColor) { // unless flashing - ctx.fillStyle = borderColor.darker().toString(); - } - - // cache my border colors - this.cachedClr = borderColor.toString(); - this.cachedClrBright = borderColor.lighter(this.contrast) - .toString(); - this.cachedClrDark = borderColor.darker(this.contrast).toString(); - - if (!this.isNumeric) { - ctx.fillRect( - this.edge, - this.edge, - this.width() - this.edge * 2, - this.height() - this.edge * 2 - ); - if (!MorphicPreferences.isFlat) { - this.drawRectBorder(ctx); - } - } else { - r = Math.max((this.height() - (this.edge * 2)) / 2, 0); - ctx.beginPath(); - ctx.arc( - r + this.edge, - r + this.edge, - r, - radians(90), - radians(-90), - false - ); - ctx.arc( - this.width() - r - this.edge, - r + this.edge, - r, - radians(-90), - radians(90), - false - ); - ctx.closePath(); - ctx.fill(); - if (!MorphicPreferences.isFlat) { - this.drawRoundBorder(ctx); - } - } - - // draw my "wish" block, if any - if (this.selectedBlock) { - ctx.drawImage( - this.doWithAlpha(1, () => this.selectedBlock.fullImage()), - this.edge + this.typeInPadding, - this.edge - ); - } }; InputSlotMorph.prototype.drawRectBorder = function (ctx) { From b49fc8309cc197a5c99b1e1cc9ce40107c41ba8f Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 00:17:17 +0000 Subject: [PATCH 068/132] fix --- src/gui.js | 59 ++---------------------------------------------------- 1 file changed, 2 insertions(+), 57 deletions(-) diff --git a/src/gui.js b/src/gui.js index 5902e5d3d5..a0f393eebc 100644 --- a/src/gui.js +++ b/src/gui.js @@ -132,7 +132,7 @@ IDE_Morph.prototype.setDefaultDesign = function () { = SpriteMorph.prototype.paletteColor.lighter(30); IDE_Morph.prototype.buttonContrast = 30; - IDE_Morph.prototype.backgroundColor = new Color(10, 10, 10); + IDE_Morph.prototype.backgroundColor = new Color(20, 20, 25); IDE_Morph.prototype.frameColor = SpriteMorph.prototype.paletteColor; IDE_Morph.prototype.groupColor @@ -1001,62 +1001,7 @@ IDE_Morph.prototype.createLogo = function () { // otherwise would be compromised by annoying browser security. // this.logo.texture = this.logoURL; // original code, commented out - this.logo.texture = "data:image/png;base64," + - "iVBORw0KGgoAAAANSUhEUgAAACwAAAAYCAYAAACBbx+6AAAKiklEQVRYR5VXe3BU5RX/" + - "ne+7924SwiOEJJvwUCAgCZFBEtRatIlVlATLIwlFsCgdeYWICu1MfbKUabVVtBoDQlUc" + - "FCubEIpAAEUTrGhFGIXAAjZCFdhNQiTkQbK7997vdO7SREAo9P5zZ77HOb9zzu87D8JV" + - "fOyBwGIwEdg5XrcmKRExcoSCNQKgWwXRTYKQDAKUQi1DbASrjzgsdqdM8zc6d6o80LIB" + - "RR6oq1B52SN0pcteL+SUKbCdcw3lCUMsof2amAs0iVRNEoIhZYKoCcTtYBARxUUZ1IMZ" + - "CIZxWDG9oVSv1/tP8Z12ZHAVNMqBdSW9l9uPAGYGoQwicqjQUQsmZ9kLSf8FGyhzzyCB" + - "P8X1kO7TLaoREJuIxCeSzKNhWzRbKhgyRCwJZfcA2UOY+E4QTewZK2Ob2tQhIl6cPLmu" + - "LKLPC+n8O2X/P+CJAXLAXXzpfLD+sqRHesaKF5vbHZtil4bCA98YeO+2f19J0Yl3+wzV" + - "DH0GMz8cE0WxHSH8DZrxhPsX3x7rBO5YUFgI1Um3y8r0sCg8WOZgBQ54YPTJGNCPgehw" + - "qNl/zfTmJoe3Dt9OeN15LgObTUs/JNB9prvA9/mljNvblCkyh+7l6p3AxVxt2JiQalty" + - "IYB5AL5n5qWh1vqVA2cieCWjz+07AXd8C+eZAP71SY8Q6JlzfuajDPFMSkHg7brtSd1w" + - "Vr2hVIymxX97f2IO2nCPP2be0EDaWZuMVttoP2tGBd5/dfCpToHnKMZUvWSJzP5ZNSin" + - "uouv9RXX/MRW9lMgHkekaqCsVZDmZnfD4JMI7LXPPUgHXATaBVEvLDrg7tBgRDbrK9wz" + - "GHwnM0Xrmsg3bT4eC5XV2FzfYnS/fkzK9zU7aQ7MXxbvnxkk8UhYUTcGTGJyMsM/Okw5" + - "s3rVdY2Zs/foe1MyIw8UHjA8oCosEUA1cjw/AA94M/KUMOcQBW8gsptYuXYpa8Cr/aZW" + - "7Sss9Mrhw33swWJkV1eL6uoc6wFPVVRDo3stmDN/xOFAed95EHYps7o/Jb/hrc6QTXt0" + - "/4QzYa1Egd7TyCq3WEgBGkggMyGhbt2bnpyrDO8PJDizAYPbbS21Tw+rXk+BjzIQvhRF" + - "8ub6MlhiF4h6dKU1J1M4xD+xvnc/CaMKpN5LntywqHM9d77vrwCNrCxNG32x0Oxs1lzp" + - "vmtdQVnfe0DArGvsczNskUAaareWDP/SOT+2qKa/DkrtLu14k8HrW+JrsKbf1xFZN3ES" + - "khrbJ7tPxYYMMRpsxQi4ajaVDjnobI8vrslWLLc6186lNYBqX041hiyoDR339ovWNGs7" + - "GA3J+XUFneDGFft+T4zfCsYDm5enrzsfdF7R12lM1jsAfcPgNmJkMqE3AfEMWqYTlVpK" + - "vcDAbSCcEUCcIO6jSyzWSW04a8rXmGAw4yQYg5nQkxi9GHhu6/L0pbnzfbcxoZIUFXd5" + - "2KlEOR5Yfm/cACFduxnCl5zvv70TWN68/YNYauVSi77BNjs2CmDVQKF/WFIyJPTzh48m" + - "GVbwCwK6E+MJJtpBLKUi+1kC3wNShbaF40KDrkM7FrQ0S5PmsyCMd5xAzHMVYRgzzbCV" + - "/jkb4Z66En/WpGuisjryFIkGsFqrWN0XAXx+NQuUpyyJ70VPnz5jfapc7RNS7mltXLly" + - "tj5nzipzbPG+gTrrTzIwQ2guTZmhHUoXxdteGnYkd/6hfUR8cMsr6dM6jcwt+nokkbkL" + - "JBdseWXY6+dH5a6iw3dLUiuYsQJEPwXQurU07b7OM3c9ery3DLceAdHHgvl1xVQYIvzG" + - "AUzshXCqTsP65NtsxioQWgAVw2w/kFLQuGfPykw9a84eqzPV3D2vZgQJ7UEp9YfYDtXa" + - "mhwvLHs5QTRvKU2b3AW4+ND1YOwQQi3cXDJ8be78QwsZGCXAUgFDCdRPET8uGGMBiqlM" + - "WDcBHo9yMkVZ2RQ7d75vEzMGMMmFUqqO0b2H/dMBGym/zBB1Fe6PwBAgvAxgBYMWpuQH" + - "3nLq/5KdrA42f+Y69WXIdFKNA2pcsW+iYLzDjBIQZwHUWlmaNqnTsNzimiywtoFhL2PI" + - "YQTOZfDbAH1B4CwCTSfiJxXTHQTun5gQk/emZ2Aw3XPA8HkywuOKfZXElFJZmjYykik9" + - "LLrSWl1F0iyXIVaFgmqa5rI+NsO680LXJufXzedIo3ZhIv/Bi75qAvwMpEChrnJ52r1d" + - "kSg6MlqStYZBxwFKZ4XpW1ek7XTuTiiq6W+SfA/Ez4FxB0EkbylNG3fem4ljoR1hoFLY" + - "eJ50Kdtq/AcjHG7cFN/XDOu7AWpOzg+kH/DCiJdJXzFLocX7s5wK9+CivZnfne3WM0rD" + - "4ZYwhWO7dbjskD6VSPwOij1MmE2E+srS9LFdmWXu4dtJU2VgOgxgqFDqKc0V827YDCaC" + - "uIgYs1hxMQTdAubbFctJ21YM2z95ti85aGA5gFGsuISIHgNwshurWyKAAxXJy7q5sLA1" + - "qGb1za9/zVnzlyeu6h7TbdbZjmNT3flYN3XBvj+22noRA8cY6CBCFJgSFdQaM6ReMlyi" + - "nEDHKkvTZ3R5f77vTmIuZYlXSNEoEPKZcRiMehAsJ4URsEIJSiPmOQT+EKAWJhoEcIKm" + - "xFxbKottVICwrrI0fTY5Pa5N8iunh2i3w2MGT2lqdhTWlSWNj4kxNp0Nth8Qoe/vSCph" + - "c2rWgYk2EE8gYZNqs1l88feSjN0RPj908AZlo3X78uG1nYBnPHYoHh0dQweh+ZCzdgjx" + - "eU5B0Q0+2MduOtAsY+Paw3qo1daeAXFSFJnLJIm+LIi6a+Hq1ctG+bwvfBq97pueg4TR" + - "42jZi/07KFDh9ib20gpPnbH/4J4ceHLPSuhZc2AeW31tVFT34Fp3ojE50Gi9n5zqn0oj" + - "0HSp0nmpNY/HIzwez1VNF+OLD35gM4W3lqbn/W/5TBRYn7iISPaxFXn7Fvi/9Hgg0tNB" + - "zpRR571mIMtgSbcokXe2PcavKLaCYR4DFBT1qvWfnFZ984IFLU4rugRVoroaqKrKsZ0e" + - "0OmxT3qzrlOC7pZojmbWmcggWylACNh2nBYb9VG4LTy9ZuqOJY/31my9dMziF3vGvDug" + - "pSPb0GWzBdkEwWSdbs/aOPxXZZHIXTAidTbzzj9Srwns35QSgzDfJdjKBon+DM1m5gwi" + - "dAjhL0yahG/+VZnqSt1dazoC9yZDZs6G5dwNbEhcBIXHAdpFZCu2NQ0kmahdWZyoubQj" + - "aLMmbc/Z9pdR6a4Qv5bzYK2ufTwmZGUoTXxnsooxGByWetPTSRPC+yN9zeVC4OBd4gF5" + - "zhsanUY/w4PwiQ19R0plvQWmpckFdd7Lyagrd29i4Nvkgrpix/DTHaboHa1HaCKMDFLh" + - "9/lIo0c9/dmUOKkpXj36+TOuPm+KU8ZYSggfYGHYpMKSP+nwhzrnSnLCWZYOutyYEpm/" + - "fOCLp9268uQXQOpGZnKKTBtLinaYAgJJojZWfCsDBSTlFPfEEzVXy/3/5UCHZlecmh0B" + - "jrfLvBAJPlC/G1PlkNza0OkP4noGW4zVhkaTTAsWsTNnkDP02XSu82oTTPOSCgJvOw85" + - "0xE09MezY9mpQp7i87IHwOJ0IiRcSNOIAdkRmZEJ5D9/VBCtnsd7nAAAAABJRU5ErkJg" + - "gg=="; + this.logo.texture = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAYCAYAAACBbx+6AAABFUlEQVRYR+WWSxLDIAxDm/sfug0Lz7gukoz5dDpllwTCsyxsrocYz3vYlOseav7u7xTAw3oQBY7WzQbT9oXAPWXtna2LzwZ0HJjBNqgGHKF88CiQqsL+f12FexsidXv+/jpwVNwDseCqiqJ1KQ9Hv2YUPe7hBqUOFDt4xy3BgGO6lN+V2qpERhZ66KwiIE+hptLzOPMlC8pXJOhhlVJW0qIiGWttA1agsXFEdbzKShQ098MS7EfZTVTZGzkj0sOZFKr6Ogo8ZYmfAl5hh8qhG8nYm4dXqPsXwCUPr1K3ovAUcOxu2VKG6ubW1oyukapFs/vFVmCfTg+RuaBUu5iqELJxxPY6qi4KOgOm5tALvG08qu5u4BeMAdgop7qh1AAAAABJRU5ErkJggg=="; this.logo.render = function (ctx) { var gradient = ctx.createLinearGradient( From e685436c8fa782c9610f775e30155b37582b8a8a Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 00:27:36 +0000 Subject: [PATCH 069/132] looks --- src/gui.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/gui.js b/src/gui.js index a0f393eebc..7f08462c45 100644 --- a/src/gui.js +++ b/src/gui.js @@ -1101,7 +1101,7 @@ IDE_Morph.prototype.createControlBar = function () { ); button.hasNeutralBackground = true; - button.corner = 12; + button.corner = 3; button.color = colors[0]; button.highlightColor = colors[1]; button.pressColor = colors[0]; @@ -1133,7 +1133,7 @@ IDE_Morph.prototype.createControlBar = function () { ); button.hasNeutralBackground = true; - button.corner = 12; + button.corner = 3; button.color = colors[0]; button.highlightColor = colors[1]; button.pressColor = colors[0]; @@ -1162,7 +1162,7 @@ IDE_Morph.prototype.createControlBar = function () { () => Process.prototype.enableSingleStepping // query ); - button.corner = 12; + button.corner = 3; button.color = colors[0]; button.highlightColor = colors[1]; button.pressColor = activeColor; @@ -1199,7 +1199,7 @@ IDE_Morph.prototype.createControlBar = function () { : true ); - button.corner = 12; + button.corner = 3; button.color = colors[0]; button.highlightColor = colors[1]; button.pressColor = colors[2]; @@ -1233,7 +1233,7 @@ IDE_Morph.prototype.createControlBar = function () { ); button.hasNeutralBackground = true; - button.corner = 12; + button.corner = 3; button.color = colors[0]; button.highlightColor = colors[1]; button.pressColor = colors[0]; @@ -1258,7 +1258,7 @@ IDE_Morph.prototype.createControlBar = function () { 'pressStart', new SymbolMorph('flag', 14) ); - button.corner = 12; + button.corner = 3; button.color = colors[0]; button.highlightColor = colors[1]; button.pressColor = colors[2]; @@ -1329,7 +1329,7 @@ IDE_Morph.prototype.createControlBar = function () { new SymbolMorph('file', 14) //'\u270E' ); - button.corner = 12; + button.corner = 3; button.color = colors[0]; button.highlightColor = colors[1]; button.pressColor = colors[2]; @@ -1352,7 +1352,7 @@ IDE_Morph.prototype.createControlBar = function () { new SymbolMorph('gears', 14) //'\u2699' ); - button.corner = 12; + button.corner = 3; button.color = colors[0]; button.highlightColor = colors[1]; button.pressColor = colors[2]; @@ -1381,7 +1381,7 @@ IDE_Morph.prototype.createControlBar = function () { ); button.hasNeutralBackground = true; - button.corner = 12; + button.corner = 3; button.color = colors[0]; button.highlightColor = colors[1]; button.pressColor = colors[0]; @@ -2271,7 +2271,7 @@ IDE_Morph.prototype.createCorralBar = function () { "addNewSprite", new SymbolMorph("turtle", 14) ); - newbutton.corner = 12; + newbutton.corner = 3; newbutton.color = colors[0]; newbutton.highlightColor = colors[1]; newbutton.pressColor = colors[2]; @@ -2292,7 +2292,7 @@ IDE_Morph.prototype.createCorralBar = function () { "paintNewSprite", new SymbolMorph("brush", 15) ); - paintbutton.corner = 12; + paintbutton.corner = 3; paintbutton.color = colors[0]; paintbutton.highlightColor = colors[1]; paintbutton.pressColor = colors[2]; @@ -2316,7 +2316,7 @@ IDE_Morph.prototype.createCorralBar = function () { "newCamSprite", new SymbolMorph("camera", 15) ); - cambutton.corner = 12; + cambutton.corner = 3; cambutton.color = colors[0]; cambutton.highlightColor = colors[1]; cambutton.pressColor = colors[2]; @@ -2355,7 +2355,7 @@ IDE_Morph.prototype.createCorralBar = function () { "undeleteSprites", new SymbolMorph("trash", 18) ); - trashbutton.corner = 12; + trashbutton.corner = 3; trashbutton.color = colors[0]; trashbutton.highlightColor = colors[1]; trashbutton.pressColor = colors[2]; @@ -11608,7 +11608,7 @@ WardrobeMorph.prototype.updateList = function () { new SymbolMorph("brush", 15) ); paintbutton.padding = 0; - paintbutton.corner = 12; + paintbutton.corner = 3; paintbutton.color = IDE_Morph.prototype.groupColor; paintbutton.highlightColor = IDE_Morph.prototype.frameColor.darker(50); paintbutton.pressColor = paintbutton.highlightColor; @@ -11632,7 +11632,7 @@ WardrobeMorph.prototype.updateList = function () { new SymbolMorph("camera", 15) ); cambutton.padding = 0; - cambutton.corner = 12; + cambutton.corner = 3; cambutton.color = IDE_Morph.prototype.groupColor; cambutton.highlightColor = IDE_Morph.prototype.frameColor.darker(50); cambutton.pressColor = paintbutton.highlightColor; @@ -12100,7 +12100,7 @@ JukeboxMorph.prototype.updateList = function () { new SymbolMorph('circleSolid', 15) ); recordButton.padding = 0; - recordButton.corner = 12; + recordbutton.corner = 3; recordButton.color = IDE_Morph.prototype.groupColor; recordButton.highlightColor = IDE_Morph.prototype.frameColor.darker(50); recordButton.pressColor = recordButton.highlightColor; From 8a6b8ee3f958824e82db6965b366e52b94011b82 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 00:31:06 +0000 Subject: [PATCH 070/132] top --- src/gui.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui.js b/src/gui.js index 7f08462c45..7d4d881fa1 100644 --- a/src/gui.js +++ b/src/gui.js @@ -1010,8 +1010,8 @@ IDE_Morph.prototype.createLogo = function () { this.width(), 0 ); - gradient.addColorStop(0, 'black'); - gradient.addColorStop(0.5, myself.frameColor.toString()); + gradient.addColorStop(0, 'rgb(20,20,25)'); + gradient.addColorStop(0.5, 'rgb(20,20,25)'); ctx.fillStyle = MorphicPreferences.isFlat ? myself.frameColor.toString() : gradient; ctx.fillRect(0, 0, this.width(), this.height()); @@ -1035,7 +1035,7 @@ IDE_Morph.prototype.createLogo = function () { myself.snapMenu(); }; - this.logo.color = BLACK; + this.logo.color = new Color(20,20,25); this.logo.setExtent(new Point(200, 28)); // dimensions are fixed this.add(this.logo); }; From 69d382d996fbefc451de88c5065eac90469332cc Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 00:35:48 +0000 Subject: [PATCH 071/132] fix --- src/gui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui.js b/src/gui.js index 7d4d881fa1..9852ae7e90 100644 --- a/src/gui.js +++ b/src/gui.js @@ -123,7 +123,7 @@ IDE_Morph.uber = Morph.prototype; IDE_Morph.prototype.setDefaultDesign = function () { MorphicPreferences.isFlat = false; - SpriteMorph.prototype.paletteColor = new Color(30, 30, 30); + SpriteMorph.prototype.paletteColor = new Color(20, 20, 25); SpriteMorph.prototype.paletteTextColor = new Color(230, 230, 230); StageMorph.prototype.paletteTextColor = SpriteMorph.prototype.paletteTextColor; From ad757d7ae955f0ceab12af9b8a3800bfaa85d40e Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 00:44:13 +0000 Subject: [PATCH 072/132] fix --- src/gui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui.js b/src/gui.js index 9852ae7e90..83b2d77829 100644 --- a/src/gui.js +++ b/src/gui.js @@ -1057,7 +1057,7 @@ IDE_Morph.prototype.createControlBar = function () { x, colors = MorphicPreferences.isFlat ? this.tabColors : [ - this.groupColor, + new Color(20, 20, 25), this.frameColor.darker(50), this.frameColor.darker(50) ], From 7852cca6a1e2a49eac61e9e01207fb5095077f91 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 00:57:21 +0000 Subject: [PATCH 073/132] fix --- src/blocks.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 76cd4b6a9b..0d04684536 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -2795,11 +2795,9 @@ function BlockLabelMorph( BlockLabelMorph.prototype.getRenderColor = function () { var block = this.parentThatIsA(BlockMorph); if (MorphicPreferences.isFlat) { - return !block || block.alpha > 0.5 ? this.color - : block.color.solid().darker(Math.max(block.alpha * 200, 0.1)); + return !block || block.color; } - return !block || block.alpha > 0.5 ? this.color - : block.color.solid().lighter(Math.max(block.alpha * 200, 0.1)); + return !block || block.color }; From 9883200bb5930bae33b8929269a1f52ebcd02bdd Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 01:24:02 +0000 Subject: [PATCH 074/132] fix --- src/blocks.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 0d04684536..7856169643 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -2803,9 +2803,7 @@ BlockLabelMorph.prototype.getRenderColor = function () { BlockLabelMorph.prototype.getShadowRenderColor = function () { var block = this.parentThatIsA(BlockMorph); - return (block && block.alpha > 0.5) ? - this.shadowColor - : CLEAR; + return CLEAR; }; // BlockSymbolMorph ////////////////////////////////////////////////////////// From 305b9ed2be7d1364f115bd879ea5e7830b2e6b62 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 01:24:50 +0000 Subject: [PATCH 075/132] fix --- src/blocks.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 7856169643..8d8906b212 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -2852,8 +2852,7 @@ BlockSymbolMorph.prototype.getRenderColor = function () { : block.color.solid().lighter(Math.max(block.alpha * 200, 0.1)); } if (this.color.eq(WHITE)) { - return block.alpha > 0.5 ? this.color - : block.color.solid().lighter(Math.max(block.alpha * 200, 0.1)); + return block.color; } return this.color; }; From da9db98137ae68cb92320f8da4166181682f3d69 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:12:44 +0000 Subject: [PATCH 076/132] commit --- src/blocks.js | 24 ++++++++++++++++-------- src/click.wav | Bin 4616 -> 5520 bytes src/morphic.js | 9 ++------- src/objects.js | 3 ++- src/threads.js | 7 +++++++ 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 8d8906b212..b7f2eff32d 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -1309,6 +1309,19 @@ SyntaxElementMorph.prototype.labelParts = { group: 'else if %b %cs', dflt: [true, null], tags: 'static widget' + }, + '%numberInputBlock': { + type: 'input', + tags: 'numeric static', + menu: { + 'Infinity':'Infinity', + '-Infinity':'-Infinity', + 'NaN':"NaN" + } + }, + '%stringInputBlock':{ + type: 'input', + tags: 'static' } }; @@ -10971,7 +10984,7 @@ InputSlotMorph.prototype.menuFromDict = function ( if (choices instanceof Function) { if (!Process.prototype.enableJS) { - menu.addItem('JavaScript extensions for Snap!\nare turned off'); + menu.addItem('JavaScript extensions for Devtools!\nare turned off'); return menu; } choices = choices.call(this); @@ -11038,7 +11051,7 @@ InputSlotMorph.prototype.menuFromDict = function ( // show the green flag symbol flag = new SymbolMorph('flag'); flag.size = this.fontSize * 1.5; - flag.setColor(new Color(0, 200, 0)); + flag.setColor(new Color(0, 255, 0)); flag.fixLayout(); menu.addItem(flag, ['__shout__go__']); } else if (choices[key] instanceof Object && @@ -11894,12 +11907,7 @@ InputSlotMorph.prototype.fixLayout = function () { } this.bounds.setExtent(new Point(width, height)); - if (this.isNumeric) { - contents.setPosition(new Point( - Math.floor(height / 2), - this.edge - ).add(new Point(this.typeInPadding, 0)).add(this.position())); - } else { + { contents.setPosition(new Point( this.edge, this.edge diff --git a/src/click.wav b/src/click.wav index 74b92147cc0dbc862ed11eb7a5ef92dce91dc1db..e2a7e63e5ded67de4371eacc820295b326fd6662 100644 GIT binary patch literal 5520 zcmW+)cUV-{)1EnZmj&rIY{UvGc8xuXy+$IjH?WWxMN#Y~_ShR56BS!xiAqc`7&Z22 z#0XX-)+qLdjlQsZ@0t1L_dWZ^@+^1Ho-^~#Th8Y_yLDS$4q#BnfnC3xIIUU$0HC}U zoRmLiA}9!em{HS4#mF;R##GDamFs%nE8Si+^BEhO65?03rz6!nq4KTJw$;~o?Ryh( zC-PAi`n%MEmw4aT z?bpP%u4urA?1E(M<2%d$sps$9&XwXE={)NkU;Jgs1J``3E>3oM__p=0>Kp92Tveb| z<_Gs?v$AD3dzHK`I^)bRcc|_jn~mSBjwK;hoTEnRRb>u&^*3kaPb_rmjvkdf#_Rv` z!#^y@e`)SC8ra+5H0z+*3ql><-ua$;Rds#aJfl7M3*F4!ujFmXF85*cjTvu+Qy^|N z=GeLzfJyu{tXE5na~MuPo2N{t?hoM@3v1{fE8Lo<6S)?CfxR#X*Q&=*-3l%4?R@K= zh1+e-Rkqd3mFZfg&tgwof-T&biaGpLm6>Y(YBkdb^*}m9-RObU)4b>owUE!@kE%Wv(x+4r($py<4=Zwx zo+RtuQ(bT|rC1lNnly($@GL$;ku;eW(oMb0`o~PS2J->@fPrvPU$MJ zj4&MbKyS#QP#tas>Uul~PpCFVk-CF^u#wKwZD?m~G#)^LmF#NkUZ7JT8h7wD-G;6~ z9RrMbxS%WQF?5~Zb1>hcs~m!3u_AP%rFt#xf(FX2`oSWqLF;)X2CGppRM#;(n1l2U zZh+;mGyKJ6paj;S7tUu7x}r1aAeZ4Nz1vz(U#STDzqa<+UGFvTSz){s+Cyy~M-%BO zjpR&j12Z888bV`O0nZ={=F8uWAPVB313cx9T!+?ME_W;UYxhH|2|t54)NGeN3;8IQ@ zAAZao;3_|*)-;5g@<$K>vHVzXw7OaTdNU1xE%*zz246ZYn3_RfQY|aiRmzobHit^a zzs7arpe@#8wPT}4Lt_k$bARVrXgP3@F&HmfsjjQ;ZIpzEaWi{T0fDMuui_DJ8;9L^ zGWWv2RBe^a1=c9j&unb=GhdlM=+EI}qndq#bZmn$StVgbTm<)d0>^VQFX2QQrjJ@x zbvgQ#w$U8&myVIyl=Diw^ODqP5epbD(z5*k70^nC441Wgvwm?3I@G;s!ho~Iqv4*8+ z;4bbZ`^%(ya0No(2@R#5TnzW6W|Md&P2ef`LM>5S;RiaV>r+iW%?G(P|4r-ZBvs}? z+<|p&nj_eVjx~WZr9VHhJ?WfXY%)>LRS? z@%%662wS96PbyC>=^XvY!(lOe3}xVZh{C-Xj02z)G=oaem&eKuKjUr?26cE7&F9as zzxoEh=IXSL>cc>E!&D}{PJc`Tc{BuIPqg81NS29NE{MjL)%&eBI)LxMN^FTcWEwgP8$967yqNClRXS5|rHz8Rw@@9MV}IO_ z&D3_)O`U}}T3`iQLAoE!rImV*_0H-ke3c;;e=ZXkf}g8M6^(PD55&R;{*J2X#nuaJ zwqC8<>kitjLpcn#!aS*tkFd`x_y|+rC6DBByi3r3j9%zC{iXgzx1;7f5*lDL{2d0s zH*iYWYbZwxU$@~JKzy2J>8biX-Gb9t3$Jk=Irs;D%Bj3Y*6Gbe4+JOGUHR*rmFCo|D!Q-=1tH6f0C0fp~KRFIMEy%9HoZZ-+E;3 zu`={;luvJ|G;iTva2&QlF57q*MN=v1f#weE)}U>&qbWQ@P*e@73zEuWCfwl%w22JC zL^qyJ^Yj}lPc*s)9itFgt1H-Wn9OM+cciVlP(Pyoq32)W!6d2Te3|k=w1^Tp9onJ^ zzrYfx3N@r+?{pTGh$`7QRS(lo^%kl6IeJce_=-&EBsEpN$2YJ;P!&ce=%~~nn_p2) z>LaW6hD}fhw)2lX5C)?|p7g|9>|hu5<^Ft}fL`l$G?@2u03G3QGF6AM_yBugV_CB)EW=r1%!LL&^s z!;k>mOm=@4AVt_meV7BLnqREZjSj_j4_x9rNt{oLQ7$;?`b3j2|MMm zn`~rIk@$>fFdG}H40T?e#75wx&4R}Jf}}uv4)vj@oaRp|&oeoR?{O3i$GNJ!@uO;s zY0?dgD`OP4fjLt79&}0+t`f8o-5Unps*;hTj$t(@p_{Z@u#x&d&&sDLkmvGFKEbu% zvf!l;*2NI)Ad`9nYQPxbyPcFO9M)P+K2+-KfG=RLu;&$64uNop_i;KOm;YGgq$b>h zefTOdrSKHEDx5L_I!bplqz8HQN|-*JLz&4YJ8HsSq5z}06@+32mR0X?01kzYJW=>5 zUn)CEkJKf)G@D#S*mQ*`%safR#;6ie-a|Z8_Bs~6;8|3eKBFr%gx~NyaLZKG#R_tU zV|Yoh(uh}TFMVGJ$-W!%eDN=3`6}lN8XwXfI>3OrxCetEk~Zn?w1Qhg5l0ASB4k%F zSXZ=kB%d&?;(bLAib_g4Q>HP5+?s`vy00VAr?&SLdy!1^ z9Oz+B^X%l<%MnGLKO}wlt|*Qo>|?zic~AGv_61*m?-v+3jC8&W2Z28C6A5p>Tt8BP?ra(Cp9 zE$(N=SdGljT*r!Iobg2g&ik%ZNO$Zkwbv1%p7JbXlvfk)iXJ)oPghsn$K#w|@4zSC z7x-pw;`7dr2fz4`)5w)+Ewwi3;fC9LL+J};vi+}nt+kC(wCBKnu%wfd*5%! z?*Fz$o>7u)b*BuPh+&QyzS=+3C)60?T2*kV;COLMciEDhf|SC$r2Xbqj;)dxIL)|G za4GAI?I}$!9aV(QbYWH4~X*bRBDwGLKDoN-Cf*mTwcXn3UYIHeTdJW zV>b0T>bu#$$fv94BUM*_RpM0~<=y~0?Rz}B+MeJ9m1QsQRn4;*PIKnH3(LOvc1m6y z=fjfg<}kE*rTGV!2`uwfU|WCiN%zR&;*tu55&1m}P85ZeWV_(7rpvwFo#HNSeMfn41O4$i|H28d0>|Mc zZl(Wr$GdV|eJpQiVLRaX)@!xb1W)pawHtijX+5z#gd4}f6kCF4+fr{GyHyWe*WKOqzT{5vB4>iLlxu?aRg>+F9fgkN zp5V2?bA(5K^@IM+wV?R9vs&@B;viQ8^G}_{uf>6XBMN>ABaATHuSR7R4c`1t@3a<~ zGtB?2htvex3CAs@b>i-8S(mMw^gZSnjqRiCp7u+&0Q(X9Bl|GhR`|xuaUL&hQ8c>v zrK_Ix1-*n>#(2A@N040^X)uSUiuVuUXVzf%AFe0nY|cZ*b@KUYF6N(jhMa7xeoYHu z9Cj2(U&IxK5hEdw{=dh@A zMP4afT0`7>Tisf})$iyDPm+wXg3I$+`R*1qQr#7m*hZ&?5iimo^oD@@5m}WaOJ+&( z3&w+@oJr)5X~rvCuJIO|z(8)sal*AxT%V#XPqV7Iz_N6LXzEXdl3dyww^et1!<+e` zc%Nl7Q7_c@X%HL}A9g|%J%~rZFpR^6P)~mA8~Q{Tu>#kor}_%D7U$FoG6`wE_<4rz z_(Jd$4U=Gmxa-Yqa7%GBWvx}F-HO#tI>DnjjxOo)qOG~mQvIOHt9YD_4b&lJQ#B!k zy6bzwxlcHeSJMIgx4uOokOP&(TTR7R7^KpLqkF<`@kvpmtA!rS zd$5WTZJbnx#l8H@k7+uMrxlW2%FsgbeVg@YsxL}@UEFyh@8;U#>^i74wL$!NFX>+k zI3w`rhArJqf+rG z7;uTti>@U}H=FZeilZBp&iml3I4Dn^OWP$!eI{$aCl~dXivJ;=Vm>UvYU)?HwdgOk zUC*UOKTn7*0_9nsSbeNuU5&0%ZAoRn!+F8bXlx4e#b-W|PrM{Ac#4wNgv+9hSLttY zY;&nEjgtKGh+6Vx@z1Nl6#XnGT6mX-aBuOfZFM`{Oi$GPX$?1myZj0FVQ*LpLGUp@ zk+cvi$+!)4k!fj9t0;{BX1k=KM_gH+*(mNQjkK;#6}T~+fJNf!x^pM~hdY6j50JO6 zX~kKSbx&GLiv^7>H~@0R6?x-T?m~m~GQFCTxSyot+2RU2;7}E7tTk$>d3@7~F%!%~ z)@8{W4Jm|n(;s{rBE@?*<@5S0Jx|>39W26Y(2a-437Ho2SCUibi^~nx5wxG9p}(ZF zna~DLV?3^fTasl)LmEtj1=6*Ba@xJ%gVP|Ie-d|6OL{a;GGUBlqG)k;GoeJ>(KYtQ zrYcw^gP+tko%_gIDNu_?&;>feeI--8k&OIGsytKt74s{(VHt^4@TA%+VEAITc zIG>+snWWMh;>{wdj(GUB!Z6!J3%0-!^ir{scjCm0ypjy^P^RgU9wn;{;254EjF`bb zFja0kmf(8vqm?AXt*4ce>W538&WLl#)DLu?_L6xV%b!a+=mce9KWxA>{0pjc4H`~^ zIcJFzp28~xy&pqWYG}PQH)xY*;c#pv=bI@#3X=@HO_I$TnccneK0`9(Q*mnn zaD>}%6<#d&6jS8X>5^g3&@Q@6THNL?3a3uef%ee(|I@~ literal 4616 zcmeH}O>b0X6vv;L&a|bqq_L3@jLD5eV+8&1#U@qWViCe}EPbGnc1WqguGb;hpEFaY2#G7)Fw?pBx##tNUT;61o|+0T zhH&A%^B=^8A}NK4socfOBFejs}xe=U~p{FJ?v z9lZ5zQO-hqn7tVfrN88(MfKJX*?O@*Zs%j!!LXTb3+7V0JGri4!)FZ)Ty` zpAKaqG($UV=8d$1^JY3$RP(i1PD}A_*3SCkcGi~=Z-|MofUrBbAnH=&DRe z*Wzr&t)fgW24WSBCJ5T(wqziKKHQh%1F==jE2&&~Mmz@9-#P9_T=BD*1BD(v^rYE=y?Y!qmGuk8%-1;vmPu*>r?MG>nS=y`SVCb@vMpBcJ!FGNU1b$AE>GXd&yDxysJaCpW(Ih794zg=cy|dp-+wV z9Qrm9a%CsYy}APr>@f9(_1(56h!}XA39W2WW!n+jzcwkIeJIbe;ax9Dq4W;LGh3T@ z)N^b^dv{ttY8yySG{>agMVh`zJOWyN!^8FE=oq%zU5Pv(6toT97rWKDS8M@N^edlpp#-=mzU7CoR$`fPEhQtBvB zEANI9iY!_r7LQJvXve6N@+-eW;8Uuzq`H22Vs@2vrwA7)cejX8xj$@KwY>Ux(f=eJ zzuG#gt=B^yEmQbG+UORW?GNM17IdSk|BzCrs-Kb9JKeOfs11X4i-9{iuFWp%->#|Y zljlxM&zwCn5W*nOZ}5AC-$8yQqj2DVlHHH2m?cqG>@TdW=){jNht<{9u=?|Axc}YP zp(w0mp^)eVTQP8%Ko0r}tO7=X5?9DB8~98>n?UsW=XnO6XW-do;C`zJU){dV9IxP1 z1FBo$H?A6I%{0HKe@x}+Y&ZGL_@H?VZZ9E(7N5NmJ$&PuL=WCa{6?$Q;3;tL@zKj~ zxc$Zx`BIZ{yFD_ntN$PPu5KoF5%%g6n!=NdfAb4D={*?$Ixb zhDkIUyUsc6;xl4{PcQdz{$8G*_UivHe7!RdgF~;v3-gPY>Nl<@$KOsqS*~B3uO&0} z&lfKxGqYFb7Un`YIX!dkOXQ|cPo0^bJaul0^Qqd+&*Kf9zdo8ZSrdU`do5$seXB>wvdE>0KoRP A6aWAK diff --git a/src/morphic.js b/src/morphic.js index 43c4f8065c..a6276d9676 100644 --- a/src/morphic.js +++ b/src/morphic.js @@ -6941,7 +6941,7 @@ SliderButtonMorph.prototype.init = function (orientation) { this.pressColor = new Color(80, 80, 160); this.userState = 'normal'; // 'highlight', 'pressed' this.is3D = false; - this.hasMiddleDip = true; + this.hasMiddleDip = false; SliderButtonMorph.uber.init.call(this, orientation); }; @@ -7037,7 +7037,6 @@ SliderButtonMorph.prototype.renderEdges = function (ctx) { 0, ctx.lineWidth ); - gradient.addColorStop(0, 'white'); gradient.addColorStop(1, this.color.toString()); ctx.strokeStyle = gradient; @@ -7053,7 +7052,6 @@ SliderButtonMorph.prototype.renderEdges = function (ctx) { h ); gradient.addColorStop(0, this.color.toString()); - gradient.addColorStop(1, 'black'); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -7070,10 +7068,7 @@ SliderButtonMorph.prototype.renderEdges = function (ctx) { ); radius = h / 4; - gradient.addColorStop(0, 'black'); - gradient.addColorStop(0.35, this.color.toString()); - gradient.addColorStop(0.65, this.color.toString()); - gradient.addColorStop(1, 'white'); + gradient.addColorStop(0, this.color.toString()); ctx.fillStyle = gradient; ctx.beginPath(); diff --git a/src/objects.js b/src/objects.js index ff0e4d853e..96e7dd2063 100644 --- a/src/objects.js +++ b/src/objects.js @@ -172,7 +172,8 @@ SpriteMorph.prototype.blockColor = { operators : new Color(98, 194, 19), variables : new Color(243, 118, 29), lists : new Color(217, 77, 17), - other: new Color(150, 150, 150) + other: new Color(150, 150, 150), + inputs: WHITE }; SpriteMorph.prototype.customCategories = new Map(); // key: name, value: color diff --git a/src/threads.js b/src/threads.js index 36e8018138..aa6eb60bac 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3158,6 +3158,13 @@ Process.prototype.newPromise = function (cmds){ return new Promise(new SnapFunction(cmds)); } +Process.prototype.StringInput = function(str){ + return JSON.parse('"'+str+'"') +} +Process.prototype.NumberInput = function (num) { + return new Number(num).valueOf() +} + Process.prototype.reportGlobalFlag = function (name) { var stage = this.homeContext.receiver.parentThatIsA(StageMorph); name = this.inputOption(name); From a070b2c000e9e472430019e3a73aa7e305ffd398 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:32:25 +0000 Subject: [PATCH 077/132] commit --- src/blocks.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index b7f2eff32d..7bf723fae4 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -5317,7 +5317,7 @@ BlockMorph.prototype.render = function (ctx) { this.cachedClrBright = this.bright(); this.cachedClrDark = this.dark(); var fill = this.color.copy() - fill.a = 0.25 + fill.a = 0 var cssfill = fill.toString(); if (MorphicPreferences.isFlat) { @@ -8085,6 +8085,9 @@ RingMorph.prototype.render = function (ctx) { ctx.fillStyle = this.cachedClrDark; ctx.beginPath(); this.outlinePath(ctx, 0); + var fill = this.color.copy() + fill.a = 0 + var cssfill = fill.toString(); // render the hole: slot.outlinePath(ctx, slot.position().subtract(pos)); @@ -8108,7 +8111,7 @@ RingMorph.prototype.render = function (ctx) { } else { // draw the flat shape // draw the outline - ctx.fillStyle = this.cachedClr; + ctx.fillStyle = cssfill; ctx.beginPath(); this.outlinePath(ctx, 0); From f00095a50c2cd57963aabf69e46a9a4e66615544 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:34:42 +0000 Subject: [PATCH 078/132] commit --- src/blocks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 7bf723fae4..3123b26c59 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -8111,7 +8111,7 @@ RingMorph.prototype.render = function (ctx) { } else { // draw the flat shape // draw the outline - ctx.fillStyle = cssfill; + /*ctx.fillStyle = cssfill; ctx.beginPath(); this.outlinePath(ctx, 0); @@ -8121,7 +8121,7 @@ RingMorph.prototype.render = function (ctx) { // ctx.closePath(); ctx.clip('evenodd'); ctx.fillRect(0, 0, this.width(), this.height()); - + */ // add 3D-Effect: this.drawEdges(ctx); } From 135af65d9c1bba986e49ab6d8d0defc13d20e8f5 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:42:38 +0000 Subject: [PATCH 079/132] commit --- src/blocks.js | 157 ++++++++++++++++++++++++-------------------------- 1 file changed, 74 insertions(+), 83 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 3123b26c59..0089a7dfc6 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -1333,8 +1333,8 @@ function SyntaxElementMorph() { SyntaxElementMorph.prototype.init = function () { this.cachedClr = null; - this.cachedClrBright = null; - this.cachedClrDark = null; + this.cachedClr = null; + this.cachedClr = null; this.cachedNormalColor = null; // for single-stepping this.isStatic = false; // if true, I cannot be exchanged @@ -5314,8 +5314,8 @@ BlockMorph.prototype.clearAlpha = function () { BlockMorph.prototype.render = function (ctx) { this.cachedClr = this.color.toString(); - this.cachedClrBright = this.bright(); - this.cachedClrDark = this.dark(); + this.cachedClr = this.bright(); + this.cachedClr = this.dark(); var fill = this.color.copy() fill.a = 0 var cssfill = fill.toString(); @@ -5368,7 +5368,7 @@ BlockMorph.prototype.drawMethodIcon = function (ctx) { if (this instanceof CommandBlockMorph) { y += this.corner; } - ctx.fillStyle = isNormal ? this.cachedClrBright : this.cachedClrDark; + ctx.fillStyle = isNormal ? this.cachedClr : this.cachedClr; // pin ctx.beginPath(); @@ -6930,7 +6930,7 @@ CommandBlockMorph.prototype.drawTopDentEdge = function (ctx, x, y) { 0, y + this.corner + this.edge ); - lowerGradient.addColorStop(0, this.cachedClrBright); + lowerGradient.addColorStop(0, this.cachedClr); lowerGradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = lowerGradient; @@ -6981,7 +6981,7 @@ CommandBlockMorph.prototype.drawBottomDentEdge = function (ctx, x, y) { y + this.corner ); lowerGradient.addColorStop(0, this.cachedClr); - lowerGradient.addColorStop(1, this.cachedClrDark); + lowerGradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = lowerGradient; ctx.beginPath(); @@ -6996,7 +6996,7 @@ CommandBlockMorph.prototype.drawBottomDentEdge = function (ctx, x, y) { y + this.corner ); rightGradient.addColorStop(0, this.cachedClr); - rightGradient.addColorStop(1, this.cachedClrDark); + rightGradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = rightGradient; ctx.beginPath(); @@ -7275,7 +7275,7 @@ HatBlockMorph.prototype.drawLeftEdge = function (ctx) { var shift = this.edge * 0.5, gradient = ctx.createLinearGradient(0, 0, this.edge, 0); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); gradient.addColorStop(1, this.cachedClr); ctx.lineWidth = this.edge; @@ -7299,7 +7299,7 @@ HatBlockMorph.prototype.drawRightEdge = function (ctx) { gradient = ctx.createLinearGradient(x - this.edge, 0, x, 0); gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; @@ -7344,7 +7344,7 @@ HatBlockMorph.prototype.drawTopLeftEdge = function (ctx) { r, r ); - gradient.addColorStop(1, this.cachedClrBright); + gradient.addColorStop(1, this.cachedClr); gradient.addColorStop(0, this.cachedClr); ctx.lineWidth = this.edge; @@ -8076,13 +8076,13 @@ RingMorph.prototype.render = function (ctx) { if (!slot) {return; } this.cachedClr = this.color.toString(); - this.cachedClrBright = this.bright(); - this.cachedClrDark = this.dark(); + this.cachedClr = this.bright(); + this.cachedClr = this.dark(); if (MorphicPreferences.isFlat) { // draw the outer filled shape // draw the outline - ctx.fillStyle = this.cachedClrDark; + ctx.fillStyle = this.cachedClr; ctx.beginPath(); this.outlinePath(ctx, 0); var fill = this.color.copy() @@ -9910,8 +9910,8 @@ CommandSlotMorph.prototype.unwind = function () { CommandSlotMorph.prototype.render = function (ctx) { this.cachedClr = this.color.toString(); - this.cachedClrBright = this.bright(); - this.cachedClrDark = this.dark(); + this.cachedClr = this.bright(); + this.cachedClr = this.dark(); ctx.fillStyle = this.cachedClr; ctx.fillRect(0, 0, this.width(), this.height()); @@ -10021,7 +10021,7 @@ CommandSlotMorph.prototype.drawEdges = function (ctx) { this.height() - this.edge ); gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrBright); + gradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -10041,7 +10041,7 @@ CommandSlotMorph.prototype.drawEdges = function (ctx) { this.height() - (this.corner + edge), this.corner + edge ); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); gradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = gradient; @@ -10064,7 +10064,7 @@ CommandSlotMorph.prototype.drawEdges = function (ctx) { 0 ); gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrBright); + gradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -10089,7 +10089,7 @@ CommandSlotMorph.prototype.drawEdges = function (ctx) { 0 ); gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -10106,7 +10106,7 @@ CommandSlotMorph.prototype.drawEdges = function (ctx) { this.corner + edge, this.corner + edge ); - gradient.addColorStop(0, this.cachedClrDark); + gradient.addColorStop(0, this.cachedClr); gradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = gradient; @@ -10129,7 +10129,7 @@ CommandSlotMorph.prototype.drawEdges = function (ctx) { this.edge ); upperGradient.addColorStop(0, this.cachedClr); - upperGradient.addColorStop(1, this.cachedClrDark); + upperGradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = upperGradient; ctx.beginPath(); @@ -10198,8 +10198,8 @@ RingCommandSlotMorph.prototype.render = function (ctx) { // init this.cachedClr = this.color.toString(); - this.cachedClrBright = this.bright(); - this.cachedClrDark = this.dark(); + this.cachedClr = this.bright(); + this.cachedClr = this.dark(); ctx.fillStyle = this.cachedClr; // only add 3D-Effect here, rendering of the flat shape happens at the @@ -10233,14 +10233,6 @@ RingCommandSlotMorph.prototype.outlinePath = function (ctx, offset) { // dent: ctx.lineTo(this.corner + ins + edge + rf * 2 + ox, edge + oy); ctx.lineTo(indent + edge + rf * 2 + ox, this.corner + edge + oy); - ctx.lineTo( - indent + edge + rf * 2 + (dent - rf * 2) + ox, - this.corner + edge + oy - ); - ctx.lineTo( - indent + edge + rf * 2 + (dent - rf * 2) + this.corner + ox, - edge + oy - ); ctx.lineTo(this.width() - this.corner - edge + ox, edge + oy); // top right: @@ -10448,8 +10440,8 @@ CSlotMorph.prototype.render = function (ctx) { // init this.cachedClr = this.color.toString(); - this.cachedClrBright = this.bright(); - this.cachedClrDark = this.dark(); + this.cachedClr = this.bright(); + this.cachedClr = this.dark(); ctx.fillStyle = this.cachedClr; // only add 3D-Effect here, rendering of the flat shape happens at the @@ -10538,8 +10530,7 @@ CSlotMorph.prototype.drawTopRightEdge = function (ctx) { y, this.corner - this.edge ); - gradient.addColorStop(0, this.cachedClrDark); - gradient.addColorStop(1, this.cachedClr); + gradient.addColorStop(0, this.cachedClr); ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; @@ -10577,7 +10568,7 @@ CSlotMorph.prototype.drawTopEdge = function (ctx, x, y) { y ); upperGradient.addColorStop(0, this.cachedClr); - upperGradient.addColorStop(1, this.cachedClrDark); + upperGradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = upperGradient; ctx.beginPath(); @@ -10592,7 +10583,7 @@ CSlotMorph.prototype.drawTopEdge = function (ctx, x, y) { y + this.corner ); lowerGradient.addColorStop(0, this.cachedClr); - lowerGradient.addColorStop(1, this.cachedClrDark); + lowerGradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = lowerGradient; ctx.beginPath(); @@ -10607,7 +10598,7 @@ CSlotMorph.prototype.drawTopEdge = function (ctx, x, y) { (y + this.corner - shift) + (shift * 0.7) ); rightGradient.addColorStop(0, this.cachedClr); - rightGradient.addColorStop(1, this.cachedClrDark); + rightGradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = rightGradient; @@ -10644,7 +10635,7 @@ CSlotMorph.prototype.drawTopLeftEdge = function (ctx) { this.corner * 2, this.corner + this.edge ); - gradient.addColorStop(0, this.cachedClrDark); + gradient.addColorStop(0, this.cachedClr); gradient.addColorStop(1, this.cachedClr); ctx.lineWidth = this.edge; @@ -10672,7 +10663,7 @@ CSlotMorph.prototype.drawRightEdge = function (ctx) { gradient = ctx.createLinearGradient(x - this.edge, 0, x, 0); gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; @@ -10702,7 +10693,7 @@ CSlotMorph.prototype.drawBottomEdge = function (ctx) { this.height() - (this.corner * 2), this.corner + this.edge ); - upperGradient.addColorStop(0, this.cachedClrBright); + upperGradient.addColorStop(0, this.cachedClr); upperGradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = upperGradient; ctx.beginPath(); @@ -10722,7 +10713,7 @@ CSlotMorph.prototype.drawBottomEdge = function (ctx) { 0, this.height() - this.corner + this.edge ); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); gradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = gradient; @@ -12171,7 +12162,7 @@ InputSlotMorph.prototype.drawRectBorder = function (ctx) { this.edge ); gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(this.edge, shift); @@ -12187,7 +12178,7 @@ InputSlotMorph.prototype.drawRectBorder = function (ctx) { 0 ); gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(shift, this.edge); @@ -12204,7 +12195,7 @@ InputSlotMorph.prototype.drawRectBorder = function (ctx) { 0, this.height() ); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); gradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -12218,7 +12209,7 @@ InputSlotMorph.prototype.drawRectBorder = function (ctx) { this.width(), 0 ); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); gradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -12258,7 +12249,7 @@ InputSlotMorph.prototype.drawRoundBorder = function (ctx) { this.edge ); gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -12278,7 +12269,7 @@ InputSlotMorph.prototype.drawRoundBorder = function (ctx) { 0, this.height() ); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); gradient.addColorStop(1, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -12305,7 +12296,7 @@ InputSlotMorph.prototype.drawRoundBorder = function (ctx) { r ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrDark); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.arc( @@ -12333,7 +12324,7 @@ InputSlotMorph.prototype.drawRoundBorder = function (ctx) { r ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.arc( @@ -12845,8 +12836,8 @@ BooleanSlotMorph.prototype.render = function (ctx) { this.parent.color : new Color(200, 200, 200); } this.cachedClr = this.color.toString(); - this.cachedClrBright = this.bright(); - this.cachedClrDark = this.dark(); + this.cachedClr = this.bright(); + this.cachedClr = this.dark(); //this.drawDiamond(ctx, this.progress); this.drawLabel(ctx); //this.drawKnob(ctx, this.progress); @@ -12932,7 +12923,7 @@ BooleanSlotMorph.prototype.drawDiamond = function (ctx, progress) { this.edge * 0.6, r + (this.edge * 0.6) ); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -12954,7 +12945,7 @@ BooleanSlotMorph.prototype.drawDiamond = function (ctx, progress) { 0, this.edge ); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -12974,7 +12965,7 @@ BooleanSlotMorph.prototype.drawDiamond = function (ctx, progress) { h ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(w - r, h - shift); @@ -12990,7 +12981,7 @@ BooleanSlotMorph.prototype.drawDiamond = function (ctx, progress) { h ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(r, h - shift); @@ -13498,9 +13489,9 @@ ColorSlotMorph.prototype.render = function (ctx) { // cache my border colors this.cachedClr = borderColor.toString(); - this.cachedClrBright = borderColor.lighter(this.contrast) + this.cachedClr = borderColor.lighter(this.contrast) .toString(); - this.cachedClrDark = borderColor.darker(this.contrast).toString(); + this.cachedClr = borderColor.darker(this.contrast).toString(); ctx.fillRect( this.edge, @@ -14713,9 +14704,9 @@ FunctionSlotMorph.prototype.render = function (ctx) { // cache my border colors this.cachedClr = borderColor.toString(); - this.cachedClrBright = borderColor.lighter(this.contrast) + this.cachedClr = borderColor.lighter(this.contrast) .toString(); - this.cachedClrDark = borderColor.darker(this.contrast).toString(); + this.cachedClr = borderColor.darker(this.contrast).toString(); if (this.isPredicate) { this.drawDiamond(ctx); @@ -14827,7 +14818,7 @@ FunctionSlotMorph.prototype.drawRounded = function (ctx) { 0, this.edge ); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -14845,7 +14836,7 @@ FunctionSlotMorph.prototype.drawRounded = function (ctx) { r ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrDark); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.arc( @@ -14860,7 +14851,7 @@ FunctionSlotMorph.prototype.drawRounded = function (ctx) { // left edge: straight vertical line gradient = ctx.createLinearGradient(0, 0, this.edge, 0); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -14882,7 +14873,7 @@ FunctionSlotMorph.prototype.drawRounded = function (ctx) { r ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.arc( @@ -14903,7 +14894,7 @@ FunctionSlotMorph.prototype.drawRounded = function (ctx) { h ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(r - shift, h - shift); @@ -14913,7 +14904,7 @@ FunctionSlotMorph.prototype.drawRounded = function (ctx) { // right edge: straight vertical line gradient = ctx.createLinearGradient(w - this.edge, 0, w, 0); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(w - shift, r + shift); @@ -14982,7 +14973,7 @@ FunctionSlotMorph.prototype.drawDiamond = function (ctx) { r, 0 ); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -14997,7 +14988,7 @@ FunctionSlotMorph.prototype.drawDiamond = function (ctx) { 0, this.edge ); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -15017,7 +15008,7 @@ FunctionSlotMorph.prototype.drawDiamond = function (ctx) { 0 ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(w - r, h - shift); @@ -15032,7 +15023,7 @@ FunctionSlotMorph.prototype.drawDiamond = function (ctx) { h ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(r + shift, h - shift); @@ -15244,8 +15235,8 @@ RingReporterSlotMorph.prototype.render = function (ctx) { // init this.cachedClr = this.color.toString(); - this.cachedClrBright = this.bright(); - this.cachedClrDark = this.dark(); + this.cachedClr = this.bright(); + this.cachedClr = this.dark(); ctx.fillStyle = this.cachedClr; // only add 3D-Effect here, rendering of the flat shape happens at the @@ -15371,7 +15362,7 @@ RingReporterSlotMorph.prototype.drawEdgesOval = function (ctx) { 0, this.edge ); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -15389,7 +15380,7 @@ RingReporterSlotMorph.prototype.drawEdgesOval = function (ctx) { r ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrDark); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.arc( @@ -15404,7 +15395,7 @@ RingReporterSlotMorph.prototype.drawEdgesOval = function (ctx) { // left edge: straight vertical line gradient = ctx.createLinearGradient(0, 0, this.edge, 0); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -15426,7 +15417,7 @@ RingReporterSlotMorph.prototype.drawEdgesOval = function (ctx) { r ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.arc( @@ -15447,7 +15438,7 @@ RingReporterSlotMorph.prototype.drawEdgesOval = function (ctx) { h ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(r - shift, h - shift); @@ -15457,7 +15448,7 @@ RingReporterSlotMorph.prototype.drawEdgesOval = function (ctx) { // right edge: straight vertical line gradient = ctx.createLinearGradient(w - this.edge, 0, w, 0); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(w - shift, r + shift); @@ -15526,7 +15517,7 @@ RingReporterSlotMorph.prototype.drawEdgesDiamond = function (ctx) { r, 0 ); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -15541,7 +15532,7 @@ RingReporterSlotMorph.prototype.drawEdgesDiamond = function (ctx) { 0, this.edge ); - gradient.addColorStop(1, this.cachedClrDark); + gradient.addColorStop(1, this.cachedClr); gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); @@ -15561,7 +15552,7 @@ RingReporterSlotMorph.prototype.drawEdgesDiamond = function (ctx) { 0 ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(w - r, h - shift); @@ -15576,7 +15567,7 @@ RingReporterSlotMorph.prototype.drawEdgesDiamond = function (ctx) { h ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); + gradient.addColorStop(0, this.cachedClr); ctx.strokeStyle = gradient; ctx.beginPath(); ctx.moveTo(r + shift, h - shift); From 29eaf825acb0fb989ec06af106c6ffcf4a843176 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 16:45:27 +0000 Subject: [PATCH 080/132] commit --- src/blocks.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 0089a7dfc6..014a7c501e 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -5314,8 +5314,6 @@ BlockMorph.prototype.clearAlpha = function () { BlockMorph.prototype.render = function (ctx) { this.cachedClr = this.color.toString(); - this.cachedClr = this.bright(); - this.cachedClr = this.dark(); var fill = this.color.copy() fill.a = 0 var cssfill = fill.toString(); @@ -8076,8 +8074,6 @@ RingMorph.prototype.render = function (ctx) { if (!slot) {return; } this.cachedClr = this.color.toString(); - this.cachedClr = this.bright(); - this.cachedClr = this.dark(); if (MorphicPreferences.isFlat) { // draw the outer filled shape @@ -9910,8 +9906,6 @@ CommandSlotMorph.prototype.unwind = function () { CommandSlotMorph.prototype.render = function (ctx) { this.cachedClr = this.color.toString(); - this.cachedClr = this.bright(); - this.cachedClr = this.dark(); ctx.fillStyle = this.cachedClr; ctx.fillRect(0, 0, this.width(), this.height()); @@ -10198,8 +10192,6 @@ RingCommandSlotMorph.prototype.render = function (ctx) { // init this.cachedClr = this.color.toString(); - this.cachedClr = this.bright(); - this.cachedClr = this.dark(); ctx.fillStyle = this.cachedClr; // only add 3D-Effect here, rendering of the flat shape happens at the @@ -10440,8 +10432,6 @@ CSlotMorph.prototype.render = function (ctx) { // init this.cachedClr = this.color.toString(); - this.cachedClr = this.bright(); - this.cachedClr = this.dark(); ctx.fillStyle = this.cachedClr; // only add 3D-Effect here, rendering of the flat shape happens at the @@ -12836,8 +12826,6 @@ BooleanSlotMorph.prototype.render = function (ctx) { this.parent.color : new Color(200, 200, 200); } this.cachedClr = this.color.toString(); - this.cachedClr = this.bright(); - this.cachedClr = this.dark(); //this.drawDiamond(ctx, this.progress); this.drawLabel(ctx); //this.drawKnob(ctx, this.progress); @@ -15235,8 +15223,6 @@ RingReporterSlotMorph.prototype.render = function (ctx) { // init this.cachedClr = this.color.toString(); - this.cachedClr = this.bright(); - this.cachedClr = this.dark(); ctx.fillStyle = this.cachedClr; // only add 3D-Effect here, rendering of the flat shape happens at the From 02f09595d2ac1dc313e4677d944482c450a9f9ff Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 17:04:36 +0000 Subject: [PATCH 081/132] commit --- src/blocks.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/blocks.js b/src/blocks.js index 014a7c501e..7cfaf97d69 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11844,6 +11844,11 @@ InputSlotMorph.prototype.fixLayout = function () { contents.enableSelecting(); contents.color = BLACK; } + { + contents.bold = this.readonly + } + if (this.isStatic) + contents.color = this.parent.color if (this.choices) { arrow.setSize(fontHeight(this.fontSize)); From df1684ada61e86b25c52c163b6d1db5b935f4729 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 17:06:23 +0000 Subject: [PATCH 082/132] commit --- src/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index 7cfaf97d69..b45156b09e 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11848,7 +11848,7 @@ InputSlotMorph.prototype.fixLayout = function () { contents.bold = this.readonly } if (this.isStatic) - contents.color = this.parent.color + contents.color = (this.parent||{color:WHITE}).color if (this.choices) { arrow.setSize(fontHeight(this.fontSize)); From 41cff2f3abc9c0a03bf48c66dbc0092a6efcf463 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 17:09:16 +0000 Subject: [PATCH 083/132] commit --- src/blocks.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index b45156b09e..1fcd0319d3 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11845,11 +11845,12 @@ InputSlotMorph.prototype.fixLayout = function () { contents.color = BLACK; } { - contents.bold = this.readonly + contents.bold = false } - if (this.isStatic) + if (this.isStatic){ contents.color = (this.parent||{color:WHITE}).color - + contents.bold = this.isReadOnly + } if (this.choices) { arrow.setSize(fontHeight(this.fontSize)); arrow.show(); From d189952bf4d43e01d228c27b2dd0876857979654 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 17:11:45 +0000 Subject: [PATCH 084/132] commit --- src/blocks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 1fcd0319d3..e1dd2e14b1 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11845,11 +11845,11 @@ InputSlotMorph.prototype.fixLayout = function () { contents.color = BLACK; } { - contents.bold = false + contents.isBold = false } if (this.isStatic){ contents.color = (this.parent||{color:WHITE}).color - contents.bold = this.isReadOnly + contents.isBold = this.isReadOnly } if (this.choices) { arrow.setSize(fontHeight(this.fontSize)); From fac8e9f2b094c286dd1aae8cbb4f2461fd346365 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 17:15:26 +0000 Subject: [PATCH 085/132] commit --- src/blocks.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/blocks.js b/src/blocks.js index e1dd2e14b1..c6351d5a70 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11844,6 +11844,7 @@ InputSlotMorph.prototype.fixLayout = function () { contents.enableSelecting(); contents.color = BLACK; } + contents.isShowingBlanks = this.isReadOnly { contents.isBold = false } From de6614616f2b230ee7825e076c0a9c514d53d13a Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 17:18:11 +0000 Subject: [PATCH 086/132] commit --- src/blocks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index c6351d5a70..154ff3c3e5 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11842,7 +11842,7 @@ InputSlotMorph.prototype.fixLayout = function () { contents.color = WHITE; } else { contents.enableSelecting(); - contents.color = BLACK; + contents.color = WHITE; } contents.isShowingBlanks = this.isReadOnly { @@ -12381,7 +12381,7 @@ InputSlotStringMorph.prototype.getRenderColor = function () { } return this.parent.alpha > 0.5 ? this.color : BLACK; } - return this.parent.alpha > 0.25 ? this.color : WHITE; + return this.color; }; InputSlotStringMorph.prototype.getShadowRenderColor = function () { From b74816a4708d0031d7872b01a457322b88f57c82 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 17:18:38 +0000 Subject: [PATCH 087/132] commit --- src/blocks.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 154ff3c3e5..399b90875f 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11877,12 +11877,7 @@ InputSlotMorph.prototype.fixLayout = function () { + this.typeInPadding * 2; } else { height = contents.height() + this.edge * 2; // + this.typeInPadding * 2 - if (this.isNumeric) { - width = contents.width() - + Math.floor(arrowWidth * 0.5) - + height - + this.typeInPadding * 2; - } else { + { width = Math.max( contents.width() + arrowWidth From db4334b38205509f423fd66e5f9efcb97cec6f4b Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 17:21:13 +0000 Subject: [PATCH 088/132] commit --- src/blocks.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index 399b90875f..9a7e07add9 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11844,13 +11844,14 @@ InputSlotMorph.prototype.fixLayout = function () { contents.enableSelecting(); contents.color = WHITE; } - contents.isShowingBlanks = this.isReadOnly + contents.isShowingBlanks = false { contents.isBold = false } if (this.isStatic){ contents.color = (this.parent||{color:WHITE}).color contents.isBold = this.isReadOnly + contents.isShowingBlanks = true } if (this.choices) { arrow.setSize(fontHeight(this.fontSize)); From d77680dcf8f259623c4dbb4ed08b860211331d79 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 17:23:27 +0000 Subject: [PATCH 089/132] commit --- src/blocks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 9a7e07add9..997c58bb08 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11844,14 +11844,14 @@ InputSlotMorph.prototype.fixLayout = function () { contents.enableSelecting(); contents.color = WHITE; } - contents.isShowingBlanks = false + contents.isShowingBlanks = true { contents.isBold = false } if (this.isStatic){ contents.color = (this.parent||{color:WHITE}).color contents.isBold = this.isReadOnly - contents.isShowingBlanks = true + contents.isShowingBlanks = false } if (this.choices) { arrow.setSize(fontHeight(this.fontSize)); From 02caef5ed1fe0bf7305d62f319c4d11b32ebb67e Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 19:33:04 +0000 Subject: [PATCH 090/132] commit --- snap.html | 5 +---- src/nativetypes.js | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/snap.html b/snap.html index b2f4d37339..255149c176 100755 --- a/snap.html +++ b/snap.html @@ -7,7 +7,7 @@ - + @@ -46,9 +46,6 @@ loop = (timestamp) => { requestAnimationFrame(loop); - if (timestamp - lastTime < 1000 / FPS) { - return; - } world.doOneCycle(); lastTime = Math.max( lastTime + 1000 / FPS, diff --git a/src/nativetypes.js b/src/nativetypes.js index 77606267ab..04008598ec 100644 --- a/src/nativetypes.js +++ b/src/nativetypes.js @@ -7,7 +7,8 @@ class SnapFunction extends Function { SnapFunction.prototype.init = function(context){ this.getContext = () => context this.context = context - return new Proxy(this, { + var proxyobj = {proxy:{}} + proxyobj.proxy = new Proxy(this, { apply: function (target, thisArg, args) { var stage = world.children[0].children[3] var proc = new Process() @@ -15,6 +16,7 @@ SnapFunction.prototype.init = function(context){ proc.initializeFor(context, new List(args)); proc.context.funct = target; stage.threads.processes.push(proc); + proc.This=thisArg proc.runStep(); if(target.Error){ throw target.Error @@ -23,6 +25,25 @@ SnapFunction.prototype.init = function(context){ target.returnValue = void 0 target.Error = void 0 return retval + }, construct : function (target, args ,funct) { + var obj = Object.create(target.prototype) + obj.constructor = proxyobj.proxy + var stage = world.children[0].children[3] + var proc = new Process() + proc.receiver = obj || stage; + proc.initializeFor(context, new List(args)); + proc.context.funct = target; + stage.threads.processes.push(proc); + proc.This = obj + proc.runStep(); + if (target.Error) { + throw target.Error + } + var retval = target.returnValue + target.returnValue = void 0 + target.Error = void 0 + if (retval instanceof proxyobj.proxy) return retval + return obj } }) } From 294fd2ac7f90e0c8e62f58eb4cb68796137f7868 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 20:29:18 +0000 Subject: [PATCH 091/132] commit --- src/blocks.js | 4 ++++ src/threads.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/blocks.js b/src/blocks.js index 997c58bb08..d3c75b519b 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -1310,6 +1310,10 @@ SyntaxElementMorph.prototype.labelParts = { dflt: [true, null], tags: 'static widget' }, + '%staticmult':{ + type:'multi', + tags: 'static' + }, '%numberInputBlock': { type: 'input', tags: 'numeric static', diff --git a/src/threads.js b/src/threads.js index aa6eb60bac..2c36decdc0 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3165,6 +3165,38 @@ Process.prototype.NumberInput = function (num) { return new Number(num).valueOf() } +Process.prototype.Function = function (inputs,body){ + body.inputs = inputs.itemsArray() + return new SnapFunction(body) +} + +Process.prototype.GetThis = function(){ + return this.This +} + +Process.prototype.JsGet = function(obj,prop){ + return obj[prop] +} + +Process.prototype.JsSet = function(obj,prop,val){ + obj[prop]=val +} + +Process.prototype.JsCallMethod = function(obj,method,inputs){ //spec:%s [ %s ] %staticmult + var val = obj[method](...inputs.itemsArray()) + if (val === void 0){ + throw new TypeError('Expected return but seen void') + } + return val +} +Process.prototype.JsRunMethod = function (obj, method, inputs) { //spec:%s [ %s ] %staticmult + return obj[method](...inputs.itemsArray()) +} + +Process.prototype.globalHtmlWorldsParent = function () { + return window +} + Process.prototype.reportGlobalFlag = function (name) { var stage = this.homeContext.receiver.parentThatIsA(StageMorph); name = this.inputOption(name); From cc67d80b5c0cacdce6d3f6877ee23e8f81bc0dc1 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 21 Aug 2024 20:56:39 +0000 Subject: [PATCH 092/132] commit --- src/objects.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/objects.js b/src/objects.js index 96e7dd2063..eaf26d33d7 100644 --- a/src/objects.js +++ b/src/objects.js @@ -3731,6 +3731,7 @@ SpriteMorph.prototype.blockTemplates = function ( blocks.push(block('newPromise')); blocks.push(block('promiseCatch')); blocks.push(block('promiseThen')); + blocks.push(block('Await')); // for debugging: /////////////// if (devMode) { From dd994119cda26d3ecc617aad1d41bb2fad651d51 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 04:56:46 +0000 Subject: [PATCH 093/132] commit --- src/objects.js | 14 ++++++++++++++ src/threads.js | 10 +++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/objects.js b/src/objects.js index eaf26d33d7..c23b062b25 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2294,6 +2294,18 @@ SpriteMorph.prototype.primitiveBlocks = function () { category: 'control', spec: 'await %ros', code: 'await' + }, + New: { + type: 'reporter', + category: 'operators', + spec: 'new %ros %staticmult', + code: 'new' + }, + Function: { + type: 'reporter', + category: 'operators', + spec: 'function $( %blockVars $){ %cl $}', + code: 'newFunct' } }; }; @@ -3805,6 +3817,7 @@ SpriteMorph.prototype.blockTemplates = function ( blocks.push(block("getStatInfo")); } else if (category === 'operators') { + blocks.push(block('Function')); blocks.push(block('reifyScript')); blocks.push(block('reifyReporter')); blocks.push(block('reifyPredicate')); @@ -3844,6 +3857,7 @@ SpriteMorph.prototype.blockTemplates = function ( blocks.push('-'); blocks.push(block('reportIsA')); blocks.push(block('reportVariadicIsIdentical')); + blocks.push(block("New")); if (Process.prototype.enableJS) { blocks.push('-'); diff --git a/src/threads.js b/src/threads.js index 2c36decdc0..3d9cc76ab0 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3165,6 +3165,10 @@ Process.prototype.NumberInput = function (num) { return new Number(num).valueOf() } +Process.prototype.New = function (funct,inputs){ + return new funct(inputs.itemsArray()) +} + Process.prototype.Function = function (inputs,body){ body.inputs = inputs.itemsArray() return new SnapFunction(body) @@ -3178,18 +3182,18 @@ Process.prototype.JsGet = function(obj,prop){ return obj[prop] } -Process.prototype.JsSet = function(obj,prop,val){ +Process.prototype.JsSet = function(obj,prop,val){ //command spec:%s [ %s ] = %s obj[prop]=val } -Process.prototype.JsCallMethod = function(obj,method,inputs){ //spec:%s [ %s ] %staticmult +Process.prototype.JsCallMethod = function(obj,method,inputs){ //reporter spec:%s [ %s ] %staticmult var val = obj[method](...inputs.itemsArray()) if (val === void 0){ throw new TypeError('Expected return but seen void') } return val } -Process.prototype.JsRunMethod = function (obj, method, inputs) { //spec:%s [ %s ] %staticmult +Process.prototype.JsRunMethod = function (obj, method, inputs) { //command spec:%s [ %s ] %staticmult return obj[method](...inputs.itemsArray()) } From 7136c5775a3ba36ac5403d8aadfb8191c6335e1d Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 05:01:34 +0000 Subject: [PATCH 094/132] commit --- src/nativetypes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nativetypes.js b/src/nativetypes.js index 04008598ec..1be04925e3 100644 --- a/src/nativetypes.js +++ b/src/nativetypes.js @@ -1,6 +1,6 @@ class SnapFunction extends Function { constructor(context){ - super() + super("alert('OH NO')") return this.init(context) } } From cc90b549c582aeeaf67145c4224c89f996da66a5 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 05:04:28 +0000 Subject: [PATCH 095/132] commit --- src/nativetypes.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nativetypes.js b/src/nativetypes.js index 1be04925e3..097135ca90 100644 --- a/src/nativetypes.js +++ b/src/nativetypes.js @@ -46,6 +46,7 @@ SnapFunction.prototype.init = function(context){ return obj } }) + return proxyobj.proxy } SnapFunction.prototype.Return = function (value){ this.returnValue = value From 791f59804febf1ad9e35fffe2d79a838cf741838 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 05:09:35 +0000 Subject: [PATCH 096/132] commit --- src/threads.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/threads.js b/src/threads.js index 3d9cc76ab0..1b41327dd1 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3149,12 +3149,15 @@ Process.prototype.Await = function (promise){ Process.prototype.promiseThen = function(promise,cmds){ + if (!cmds) return promise.then(cmds); return promise.then(new SnapFunction(cmds)); } Process.prototype.promiseCatch = function (promise, cmds) { + if (!cmds) return promise.catch(cmds); return promise.catch(new SnapFunction(cmds)); } -Process.prototype.newPromise = function (cmds){ +Process.prototype.newPromise = function (cmds) { + if (!cmds) return new Promise(cmds); return new Promise(new SnapFunction(cmds)); } @@ -3170,6 +3173,7 @@ Process.prototype.New = function (funct,inputs){ } Process.prototype.Function = function (inputs,body){ + body = body||new Context() body.inputs = inputs.itemsArray() return new SnapFunction(body) } From fdf450c69b5fbb74597c262f37046cc88fa5d9d9 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 05:16:13 +0000 Subject: [PATCH 097/132] commit --- src/blocks.js | 6 ++++++ src/objects.js | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index d3c75b519b..9000df5b5b 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -1163,6 +1163,12 @@ SyntaxElementMorph.prototype.labelParts = { tags: 'widget', min: 1 }, + '%inputs': { + type: 'multi', + slots: '%t', + tags: 'widget', + min: 0 + }, '%blockVars': { type: 'multi', slots: '%t', diff --git a/src/objects.js b/src/objects.js index c23b062b25..49b690754f 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2304,7 +2304,7 @@ SpriteMorph.prototype.primitiveBlocks = function () { Function: { type: 'reporter', category: 'operators', - spec: 'function $( %blockVars $){ %cl $}', + spec: 'function $( %inputs $){ %cl $}', code: 'newFunct' } }; From 46fb2b82e10e4d4e9c0a0e4d0afc8bbaddcebfcf Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 05:20:00 +0000 Subject: [PATCH 098/132] commit --- src/blocks.js | 2 +- src/objects.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 9000df5b5b..52ef6df54f 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -1163,7 +1163,7 @@ SyntaxElementMorph.prototype.labelParts = { tags: 'widget', min: 1 }, - '%inputs': { + '%inputParams': { type: 'multi', slots: '%t', tags: 'widget', diff --git a/src/objects.js b/src/objects.js index 49b690754f..a9fb22daf0 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2304,7 +2304,7 @@ SpriteMorph.prototype.primitiveBlocks = function () { Function: { type: 'reporter', category: 'operators', - spec: 'function $( %inputs $){ %cl $}', + spec: 'function $( %inputParams $){ %cl $}', code: 'newFunct' } }; From 144ebefe1dfc762528b81e83f4c644db794f2ba0 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 05:44:27 +0000 Subject: [PATCH 099/132] commit --- src/threads.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/threads.js b/src/threads.js index 1b41327dd1..d3a92da43e 100644 --- a/src/threads.js +++ b/src/threads.js @@ -980,6 +980,7 @@ Process.prototype.reportBasicAnd = function (a, b) { Process.prototype.doReport = function (block) { var outer = this.context.outerContext; + var ctx = this.context; if (this.flashContext()) {return; } // flash the block here, special form if (this.isClicked && (block.topBlock() === this.topBlock)) { this.isShowingResult = true; @@ -1008,16 +1009,16 @@ Process.prototype.doReport = function (block) { // in any case evaluate (and ignore) // the input, because it could be // an HTTP Request for a hardware extension - if (this.context.funct){ + if (ctx.funct){ if (block.inputs()[0] instanceof BlockMorph){ - this.context.funct.Return(this.evaluateBlock(block.inputs()[0], block.inputs()[0].inputs().length)) + ctx.funct.Return(this.evaluateBlock(block.inputs()[0], block.inputs()[0].inputs().length)) this.readyToYield = true; this.readyToTerminate = true; this.errorFlag = false; this.canBroadcast = false; return } - this.context.funct.Return(this.evaluateInput(block.inputs()[0])); + ctx.funct.Return(this.evaluateInput(block.inputs()[0])); this.readyToYield = true; this.readyToTerminate = true; this.errorFlag = false; From 2b3bb567ad9f456326bb4e6f9b9ccd1987565aa6 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 08:15:58 +0000 Subject: [PATCH 100/132] commit --- src/threads.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/threads.js b/src/threads.js index d3a92da43e..c3433f9ea4 100644 --- a/src/threads.js +++ b/src/threads.js @@ -978,9 +978,22 @@ Process.prototype.reportBasicAnd = function (a, b) { return a && b; }; +Process.prototype.Return = function(output){ + this.context.outerContext.funct.Return(output); + this.context.expression.selector = "doReport" + this.readyToYield = true; + this.readyToTerminate = true; + this.errorFlag = false; + this.canBroadcast = false; +} + Process.prototype.doReport = function (block) { var outer = this.context.outerContext; var ctx = this.context; + if (ctx.funct) { + block.selector = "Return" + this.pushContext(block,ctx) + } if (this.flashContext()) {return; } // flash the block here, special form if (this.isClicked && (block.topBlock() === this.topBlock)) { this.isShowingResult = true; From 33f577eb7a363836357520709d4b1cfe9af580d8 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:04:38 +0000 Subject: [PATCH 101/132] commit --- src/blocks.js | 15 +++++++++++++++ src/objects.js | 8 +++++++- src/threads.js | 5 ----- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 52ef6df54f..0ffc747e0c 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -3037,6 +3037,21 @@ function BlockMorph() { } BlockMorph.prototype.init = function () { + var selector = null + Object.defineProperty(this,'selector',{ + get(){ + if ((selector === "doReport") && ((this.parent || {}).selector === "Function")){ + return 'Return' + } + if ((selector === "Return") && ((this.parent || {}).selector !== "Function")) { + return 'doReport' + } + return selector + }, + set(val){ + selector = val + } + }) this.selector = null; // name of method to be triggered this.blockSpec = ''; // formal description of label and arguments this.comment = null; // optional "sticky" comment morph diff --git a/src/objects.js b/src/objects.js index a9fb22daf0..bf710bdfe1 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2306,7 +2306,13 @@ SpriteMorph.prototype.primitiveBlocks = function () { category: 'operators', spec: 'function $( %inputParams $){ %cl $}', code: 'newFunct' - } + }, + Return: { //the same as doReport and switches between this and doReport + type: 'command', + category: 'control', + spec: 'report %s', + code: 'report' + }, }; }; diff --git a/src/threads.js b/src/threads.js index c3433f9ea4..7c4f974223 100644 --- a/src/threads.js +++ b/src/threads.js @@ -980,7 +980,6 @@ Process.prototype.reportBasicAnd = function (a, b) { Process.prototype.Return = function(output){ this.context.outerContext.funct.Return(output); - this.context.expression.selector = "doReport" this.readyToYield = true; this.readyToTerminate = true; this.errorFlag = false; @@ -990,10 +989,6 @@ Process.prototype.Return = function(output){ Process.prototype.doReport = function (block) { var outer = this.context.outerContext; var ctx = this.context; - if (ctx.funct) { - block.selector = "Return" - this.pushContext(block,ctx) - } if (this.flashContext()) {return; } // flash the block here, special form if (this.isClicked && (block.topBlock() === this.topBlock)) { this.isShowingResult = true; From 68c66e6ea9cc63e87422c43c9055546f1d82d1cf Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:11:21 +0000 Subject: [PATCH 102/132] commit --- src/blocks.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 0ffc747e0c..aacd9dc62f 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -3040,17 +3040,17 @@ BlockMorph.prototype.init = function () { var selector = null Object.defineProperty(this,'selector',{ get(){ - if ((selector === "doReport") && ((this.parent || {}).selector === "Function")){ + if ((this.select === "doReport") && ((this.parent || {}).select === "Function")){ return 'Return' } - if ((selector === "Return") && ((this.parent || {}).selector !== "Function")) { + if ((this.select === "Return") && ((this.parent || {}).select !== "Function")) { return 'doReport' } - return selector + return this.select }, set(val){ - selector = val - } + this.select = val + }, configurable:false }) this.selector = null; // name of method to be triggered this.blockSpec = ''; // formal description of label and arguments From d6750c255db185f3d6c605018942fe6f36477b4b Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:14:50 +0000 Subject: [PATCH 103/132] commit --- src/threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/threads.js b/src/threads.js index 7c4f974223..f0eee36f7e 100644 --- a/src/threads.js +++ b/src/threads.js @@ -979,7 +979,7 @@ Process.prototype.reportBasicAnd = function (a, b) { }; Process.prototype.Return = function(output){ - this.context.outerContext.funct.Return(output); + this.context.funct.Return(output); this.readyToYield = true; this.readyToTerminate = true; this.errorFlag = false; From 8cbaf8014bf2ad3e71e1fa7a26d52c42f431c3bd Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:22:08 +0000 Subject: [PATCH 104/132] commit --- src/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index aacd9dc62f..5a34bf972a 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -3050,7 +3050,7 @@ BlockMorph.prototype.init = function () { }, set(val){ this.select = val - }, configurable:false + }, configurable:false,enumerable:true }) this.selector = null; // name of method to be triggered this.blockSpec = ''; // formal description of label and arguments From 58d820fd9ec34e21b3e835621eed88a3073954f1 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:38:04 +0000 Subject: [PATCH 105/132] commit --- src/blocks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 5a34bf972a..b01c04b50b 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -3040,10 +3040,10 @@ BlockMorph.prototype.init = function () { var selector = null Object.defineProperty(this,'selector',{ get(){ - if ((this.select === "doReport") && ((this.parent || {}).select === "Function")){ + if ((this.select === "doReport") && ((this.parent.parent || {}).select === "Function")){ return 'Return' } - if ((this.select === "Return") && ((this.parent || {}).select !== "Function")) { + if ((this.select === "Return") && ((this.parent.parent || {}).select !== "Function")) { return 'doReport' } return this.select From a3725e4c67a97996a18c8c22cd61009cb0a1afe0 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:39:58 +0000 Subject: [PATCH 106/132] commit --- src/blocks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index b01c04b50b..4810034b49 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -3040,10 +3040,10 @@ BlockMorph.prototype.init = function () { var selector = null Object.defineProperty(this,'selector',{ get(){ - if ((this.select === "doReport") && ((this.parent.parent || {}).select === "Function")){ + if ((this.select === "doReport") && (((this.parent || {}).parent || {}).select === "Function")){ return 'Return' } - if ((this.select === "Return") && ((this.parent.parent || {}).select !== "Function")) { + if ((this.select === "Return") && (((this.parent || {}).parent || {}).select !== "Function")) { return 'doReport' } return this.select From c946f75a39a8d6748f21a1fbf08bf3f012f4dffe Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:53:44 +0000 Subject: [PATCH 107/132] commit --- src/objects.js | 2 +- src/threads.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objects.js b/src/objects.js index bf710bdfe1..909979dde2 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2304,7 +2304,7 @@ SpriteMorph.prototype.primitiveBlocks = function () { Function: { type: 'reporter', category: 'operators', - spec: 'function $( %inputParams $){ %cl $}', + spec: 'function $( %inputParams $){ %c $}', code: 'newFunct' }, Return: { //the same as doReport and switches between this and doReport diff --git a/src/threads.js b/src/threads.js index f0eee36f7e..0c69c75cfd 100644 --- a/src/threads.js +++ b/src/threads.js @@ -979,7 +979,7 @@ Process.prototype.reportBasicAnd = function (a, b) { }; Process.prototype.Return = function(output){ - this.context.funct.Return(output); + this.ReturnVal(output); this.readyToYield = true; this.readyToTerminate = true; this.errorFlag = false; @@ -3182,7 +3182,7 @@ Process.prototype.New = function (funct,inputs){ } Process.prototype.Function = function (inputs,body){ - body = body||new Context() + body = new Context(null,body) body.inputs = inputs.itemsArray() return new SnapFunction(body) } From 42c70cc167cbea690714d1ae1735cf03838a037c Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 19:03:33 +0000 Subject: [PATCH 108/132] commit --- src/nativetypes.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/nativetypes.js b/src/nativetypes.js index 097135ca90..eb736f132f 100644 --- a/src/nativetypes.js +++ b/src/nativetypes.js @@ -54,6 +54,9 @@ SnapFunction.prototype.Return = function (value){ SnapFunction.prototype.Throw = function (error) { this.Error = error } +SnapFunction.prototype.toString = function (indent = 4){ + return this.context.expression.toLisp(indent) +} Error.prototype.toString = function(){ return localize(this.name) + '\n' + this.message From 65549be6f31e45571f69a81cee8480b980878adb Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 19:08:44 +0000 Subject: [PATCH 109/132] commit --- src/nativetypes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nativetypes.js b/src/nativetypes.js index eb736f132f..d36336feed 100644 --- a/src/nativetypes.js +++ b/src/nativetypes.js @@ -55,7 +55,7 @@ SnapFunction.prototype.Throw = function (error) { this.Error = error } SnapFunction.prototype.toString = function (indent = 4){ - return this.context.expression.toLisp(indent) + return 'function ('+ this.context.inputs +')\n'+ (this.context.expression||{toLisp(){return "[blank]"}}).toLisp(indent) } Error.prototype.toString = function(){ From 70211076d93b937395b622e5962a1053ebda93b9 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Thu, 22 Aug 2024 19:22:12 +0000 Subject: [PATCH 110/132] commit --- src/threads.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/threads.js b/src/threads.js index 0c69c75cfd..1acc0ad22e 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3158,15 +3158,15 @@ Process.prototype.Await = function (promise){ Process.prototype.promiseThen = function(promise,cmds){ - if (!cmds) return promise.then(cmds); + if (cmds instanceof Function) return promise.then(cmds); return promise.then(new SnapFunction(cmds)); } Process.prototype.promiseCatch = function (promise, cmds) { - if (!cmds) return promise.catch(cmds); + if (cmds instanceof Function) return promise.catch(cmds); return promise.catch(new SnapFunction(cmds)); } Process.prototype.newPromise = function (cmds) { - if (!cmds) return new Promise(cmds); + if (cmds instanceof Function) return new Promise(cmds); return new Promise(new SnapFunction(cmds)); } From 9e97d9c6a5f89dd0760b00317d8dd3172a1c379c Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Fri, 23 Aug 2024 00:00:20 +0000 Subject: [PATCH 111/132] commit --- src/objects.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/objects.js b/src/objects.js index 909979dde2..4c31722462 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2307,6 +2307,12 @@ SpriteMorph.prototype.primitiveBlocks = function () { spec: 'function $( %inputParams $){ %c $}', code: 'newFunct' }, + globalHtmlWorldsParent: { + type: 'reporter', + category: 'variables', + spec: 'window', + code: 'get window' + }, Return: { //the same as doReport and switches between this and doReport type: 'command', category: 'control', @@ -3884,6 +3890,8 @@ SpriteMorph.prototype.blockTemplates = function ( } else if (category === 'variables') { blocks.push(this.makeVariableButton()); + blocks.push(watcherToggle('globalHtmlWorldsParent')); + blocks.push(block('globalHtmlWorldsParent')); if (this.deletableVariableNames().length > 0) { blocks.push(this.deleteVariableButton()); } From ea0bbb4bac56a6b66c6c93b179c68b1490b2f450 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Fri, 23 Aug 2024 01:37:00 +0000 Subject: [PATCH 112/132] commit --- src/threads.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/threads.js b/src/threads.js index 1acc0ad22e..c9472d5ae9 100644 --- a/src/threads.js +++ b/src/threads.js @@ -1121,7 +1121,8 @@ Process.prototype.isAutoLambda = function (inputSlot) { 'doWarp', 'doFor', 'doForEach', - 'reportBlocksNative' + 'reportBlocksNative', + 'Function' ].includes(inputSlot.parent?.selector)) { // special cases when overloading those primitives // with custom block definitions @@ -6759,6 +6760,12 @@ Process.prototype.reportBasicAttributeOf = function (attribute, name) { thatObj, stage; + if (attribute instanceof Function){ + return attribute.bind(name) + } + if (!isSnapObject(name) && typeof(name)!=='string'){ + return name[attribute] + } if (name instanceof Context && attribute instanceof Context) { if (attribute?.expression.selector === 'reportEnvironment') { this.returnValueToParentContext(this.reportEnvironment( @@ -6769,6 +6776,7 @@ Process.prototype.reportBasicAttributeOf = function (attribute, name) { } return this.reportContextFor(attribute, name); } + if (thisObj) { this.assertAlive(thisObj); stage = thisObj.parentThatIsA(StageMorph); From ad5aef870ba5afb3c7d95b9506fdefc288f2e6a9 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Fri, 23 Aug 2024 02:24:20 +0000 Subject: [PATCH 113/132] commit --- src/threads.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/threads.js b/src/threads.js index c9472d5ae9..3d3c018701 100644 --- a/src/threads.js +++ b/src/threads.js @@ -6748,11 +6748,7 @@ Process.prototype.reportAttributeOf = function (attribute, name) { // sprite-local variables. Attributes such as "width", "direction" etc. // can only be queried via the dropdown menu and are, therefore, not // reachable as dyadic inputs - return this.hyper( - (att, obj) => this.reportBasicAttributeOf(att, obj), - attribute, - name - ); + return this.reportBasicAttributeOf(att, obj) }; Process.prototype.reportBasicAttributeOf = function (attribute, name) { From 5205734d55ebc9d527e1545c5320cad1b24ea699 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Fri, 23 Aug 2024 02:50:51 +0000 Subject: [PATCH 114/132] commit --- src/blocks.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index 4810034b49..d994470f8d 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11619,7 +11619,9 @@ InputSlotMorph.prototype.attributesMenu = function (searching) { varNames; if (searching) {return dict; } - + if (block.inputs()[1].selector === 'globalHtmlWorldsParent'){ + return Object.keys(window) + } block = this.parentThatIsA(BlockMorph); objName = block.inputs()[1].evaluate(); rcvr = block.scriptTarget(); From 2cfbe9c76912f065a584db43216ec288677c462c Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Fri, 23 Aug 2024 02:57:12 +0000 Subject: [PATCH 115/132] commit --- src/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index d994470f8d..2b989491aa 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11619,7 +11619,7 @@ InputSlotMorph.prototype.attributesMenu = function (searching) { varNames; if (searching) {return dict; } - if (block.inputs()[1].selector === 'globalHtmlWorldsParent'){ + if (this.parentThatIsA(BlockMorph).inputs()[1].selector === 'globalHtmlWorldsParent'){ return Object.keys(window) } block = this.parentThatIsA(BlockMorph); From f7d62e0fa100b126a91da49a0394ef3903352400 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Fri, 23 Aug 2024 03:05:36 +0000 Subject: [PATCH 116/132] commit --- src/blocks.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index 2b989491aa..54a9e50692 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11620,7 +11620,11 @@ InputSlotMorph.prototype.attributesMenu = function (searching) { if (searching) {return dict; } if (this.parentThatIsA(BlockMorph).inputs()[1].selector === 'globalHtmlWorldsParent'){ - return Object.keys(window) + dict = {} + for (let val in Object.keys(window)){ + dict.val = val + } + return dict } block = this.parentThatIsA(BlockMorph); objName = block.inputs()[1].evaluate(); From 3cbb27ff7e3e08db7d2ae92bdd17a1414932fdf4 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Fri, 23 Aug 2024 03:09:13 +0000 Subject: [PATCH 117/132] commit --- src/blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index 54a9e50692..d4bbe65289 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11622,7 +11622,7 @@ InputSlotMorph.prototype.attributesMenu = function (searching) { if (this.parentThatIsA(BlockMorph).inputs()[1].selector === 'globalHtmlWorldsParent'){ dict = {} for (let val in Object.keys(window)){ - dict.val = val + dict[val] = val } return dict } From 4caa269f0382a0aea55720fcee466162de20f4bc Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Fri, 23 Aug 2024 04:04:38 +0000 Subject: [PATCH 118/132] commit --- src/blocks.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index d4bbe65289..85d36a16b9 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -11621,9 +11621,9 @@ InputSlotMorph.prototype.attributesMenu = function (searching) { if (searching) {return dict; } if (this.parentThatIsA(BlockMorph).inputs()[1].selector === 'globalHtmlWorldsParent'){ dict = {} - for (let val in Object.keys(window)){ - dict[val] = val - } + Object.keys(window).forEach((v)=>{ + dict[v]=v + }) return dict } block = this.parentThatIsA(BlockMorph); From e32f07a436e88cb7181d79f0eac50541bbb90639 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Fri, 23 Aug 2024 04:10:28 +0000 Subject: [PATCH 119/132] commit --- src/threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/threads.js b/src/threads.js index 3d3c018701..fb7c67519c 100644 --- a/src/threads.js +++ b/src/threads.js @@ -6748,7 +6748,7 @@ Process.prototype.reportAttributeOf = function (attribute, name) { // sprite-local variables. Attributes such as "width", "direction" etc. // can only be queried via the dropdown menu and are, therefore, not // reachable as dyadic inputs - return this.reportBasicAttributeOf(att, obj) + return this.reportBasicAttributeOf(...Array.from(arguments)) }; Process.prototype.reportBasicAttributeOf = function (attribute, name) { From bbfe03a0606c84cc1322f8327781fea7f44e3ac3 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Fri, 23 Aug 2024 04:56:36 +0000 Subject: [PATCH 120/132] commit --- src/threads.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/threads.js b/src/threads.js index fb7c67519c..b2b0a050e8 100644 --- a/src/threads.js +++ b/src/threads.js @@ -3183,7 +3183,7 @@ Process.prototype.New = function (funct,inputs){ } Process.prototype.Function = function (inputs,body){ - body = new Context(null,body) + body = new Context(null,body,this.context) body.inputs = inputs.itemsArray() return new SnapFunction(body) } From fb90c5ada3c32145250c9dae34e353ea17dab251 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 7 Sep 2024 01:51:07 +0000 Subject: [PATCH 121/132] commit --- src/blocks.js | 4 ++++ src/objects.js | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/blocks.js b/src/blocks.js index 85d36a16b9..ed09c0b83d 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -1332,6 +1332,10 @@ SyntaxElementMorph.prototype.labelParts = { '%stringInputBlock':{ type: 'input', tags: 'static' + }, + '%anyBlock': { + type: 'input', + tags: 'read-only' } }; diff --git a/src/objects.js b/src/objects.js index 4c31722462..5881b1acb0 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2319,6 +2319,17 @@ SpriteMorph.prototype.primitiveBlocks = function () { spec: 'report %s', code: 'report' }, + GetThis :{ + type: 'reporter', + category: 'variables', + code:'this', + spec: 'this' + }, + JsSet: { + type: 'command', + code: 'setProp', + spec: '%anyBlock $[ %anyBlock $]= %anyBlock' + } }; }; @@ -3892,6 +3903,7 @@ SpriteMorph.prototype.blockTemplates = function ( blocks.push(this.makeVariableButton()); blocks.push(watcherToggle('globalHtmlWorldsParent')); blocks.push(block('globalHtmlWorldsParent')); + blocks.push(block('GetThis')); if (this.deletableVariableNames().length > 0) { blocks.push(this.deleteVariableButton()); } @@ -3916,6 +3928,7 @@ SpriteMorph.prototype.blockTemplates = function ( } blocks.push(block('doSetVar')); + blocks.push(block('JsSet')); blocks.push(block('doChangeVar')); blocks.push(block('doShowVar')); blocks.push(block('doHideVar')); From 321867e3a8a98e4d0086fd6512abf5215b4ec093 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 7 Sep 2024 01:59:00 +0000 Subject: [PATCH 122/132] commit --- src/objects.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/objects.js b/src/objects.js index 5881b1acb0..d9e9b2c8c0 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2328,7 +2328,14 @@ SpriteMorph.prototype.primitiveBlocks = function () { JsSet: { type: 'command', code: 'setProp', + category: 'variables', spec: '%anyBlock $[ %anyBlock $]= %anyBlock' + }, + StringInput: { + type:'reporter', + spec: '" %stringInputBlock "', + category: 'inputs', + } }; }; @@ -3839,7 +3846,7 @@ SpriteMorph.prototype.blockTemplates = function ( blocks.push('-') blocks.push(block("getStatInfo")); } else if (category === 'operators') { - + blocks.push(block('StringInput')) blocks.push(block('Function')); blocks.push(block('reifyScript')); blocks.push(block('reifyReporter')); From 14b0601c60efe2448c0285c126fe54197f116503 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 7 Sep 2024 02:44:05 +0000 Subject: [PATCH 123/132] commit --- src/objects.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/objects.js b/src/objects.js index d9e9b2c8c0..976756edae 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2336,6 +2336,12 @@ SpriteMorph.prototype.primitiveBlocks = function () { spec: '" %stringInputBlock "', category: 'inputs', + }, + NumberInput: { + type: 'reporter', + spec: '%numberInputBlock', + category: 'inputs', + } }; }; @@ -3847,6 +3853,7 @@ SpriteMorph.prototype.blockTemplates = function ( blocks.push(block("getStatInfo")); } else if (category === 'operators') { blocks.push(block('StringInput')) + blocks.push(block('NumberInput')) blocks.push(block('Function')); blocks.push(block('reifyScript')); blocks.push(block('reifyReporter')); From 2339e7142ed442ff03a752f68343bd5422245776 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 7 Sep 2024 03:42:25 +0000 Subject: [PATCH 124/132] commit --- src/morphic.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/morphic.js b/src/morphic.js index a6276d9676..a158da1464 100644 --- a/src/morphic.js +++ b/src/morphic.js @@ -3296,7 +3296,7 @@ Morph.prototype.stepFrame = function () { nxt.call(this); } this.step(); - this.children.forEach(child => child.stepFrame()); + this.children.forEach(child => { try{child.stepFrame()}catch(err){console.err(err)}}); } }; @@ -3579,7 +3579,11 @@ Morph.prototype.getImage = function () { if (this.isCachingImage) { this.cachedImage = img; } + try{ this.render(img.getContext('2d')); + } catch(err) { + console.error(err) + } this.shouldRerender = false; return img; }; From 59a31a3f5705635e922976a13c606ee83769735f Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 7 Sep 2024 04:11:24 +0000 Subject: [PATCH 125/132] commit --- src/morphic.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/morphic.js b/src/morphic.js index a158da1464..7ac9ffff93 100644 --- a/src/morphic.js +++ b/src/morphic.js @@ -12117,7 +12117,11 @@ WorldMorph.prototype.updateBroken = function () { this.condenseDamages(); this.broken.forEach(rect => { if (rect.extent().gt(ZERO)) { + try{ this.fullDrawOn(ctx, rect); + }catch(err){ + console.error(err) + } } }); this.broken = []; From b78b79e4bf294a240608989ae095a06660666062 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 7 Sep 2024 04:20:21 +0000 Subject: [PATCH 126/132] commit --- src/morphic.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/morphic.js b/src/morphic.js index 7ac9ffff93..21997c5233 100644 --- a/src/morphic.js +++ b/src/morphic.js @@ -3681,7 +3681,11 @@ Morph.prototype.drawOn = function (ctx, rect) { ctx.rect(clipped.left(), clipped.top(), clipped.width(), clipped.height()); ctx.clip(); ctx.translate(pos.x, pos.y); + try{ this.render(ctx); + }catch(err){ + console.error(err) + } if (MorphicPreferences.showHoles) { // debug hole rendering ctx.translate(-pos.x, -pos.y); ctx.globalAlpha = 0.25; From 5f38fab3813eb40b764763a1ad0d3d87112b1bf3 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 7 Sep 2024 04:46:58 +0000 Subject: [PATCH 127/132] commit --- src/blocks.js | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index ed09c0b83d..20f5a1005c 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -2647,7 +2647,7 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic, target) { } else if (isString(value)) { // shorten the string, commented out because we now scroll it // txt = value.length > 500 ? value.slice(0, 500) + '...' : value; - txt = value; + txt = JSON.stringify(value); maxHeight = ide.height() / 2; morphToShow = new TextMorph( txt, @@ -2683,11 +2683,43 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic, target) { return menu; }; } else { - return this.showBubble( - display(value), - exportPic, - target + // shorten the string, commented out because we now scroll it + // txt = value.length > 500 ? value.slice(0, 500) + '...' : value; + txt = value+""; + maxHeight = ide.height() / 2; + morphToShow = new TextMorph( + txt, + this.fontSize ); + + if (morphToShow.height() > maxHeight) { // scroll + scroller = new ScrollFrameMorph(); + scroller.acceptsDrops = false; + scroller.contents.acceptsDrops = false; + scroller.bounds.setWidth(morphToShow.width()); + scroller.bounds.setHeight(maxHeight); + scroller.addContents(morphToShow); + scroller.color = new Color(0, 0, 0, 0); + morphToShow = scroller; + } + + // support exporting text / numbers directly from result bubbles: + morphToShow.userMenu = function () { + var menu = new MenuMorph(this); + menu.addItem( + 'export', + () => ide.saveFileAs( + value, + 'text/plain;charset=utf-8', + localize('data') + ) + ); + menu.addItem( + 'copy', + () => writeClipboardText(value, ide) + ); + return menu; + }; } if (ide && (ide.currentSprite !== target)) { if (target instanceof StageMorph) { From 281afecfa03dd7a8eac00269d4a38d81ffdf2f3a Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 7 Sep 2024 18:49:21 +0000 Subject: [PATCH 128/132] commit --- src/objects.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/objects.js b/src/objects.js index 976756edae..ac229f501a 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2342,6 +2342,24 @@ SpriteMorph.prototype.primitiveBlocks = function () { spec: '%numberInputBlock', category: 'inputs', + }, + JsGet: { + type: 'reporter', + code: 'getProp', + spec: '%anyBlock $[ %anyBlock $]', + category: 'sensing' + }, + JsCallMethod: { + type: 'reporter', + code: 'callMethod', + spec: '%anyBlock $[ %anyBlock $]( %staticmult )', + category: 'control' + }, + JsRunMethod: { + type: 'command', + code: 'RunMethod', + spec: '%anyBlock $[ %anyBlock $]( %staticmult )', + category: 'control' } }; }; @@ -3756,6 +3774,8 @@ SpriteMorph.prototype.blockTemplates = function ( blocks.push(block('doRun')); blocks.push(block('fork')); blocks.push(block('evaluate')); + blocks.push(block('JsCallMethod')); + blocks.push(block('JsRunMethod')); blocks.push(block('reportPipe')); blocks.push('-'); blocks.push(block('doTellTo')); @@ -3823,6 +3843,7 @@ SpriteMorph.prototype.blockTemplates = function ( blocks.push(block('reportDate')); blocks.push('-'); blocks.push(block('reportAttributeOf')); + blocks.push(block('JsGet')); if (SpriteMorph.prototype.enableFirstClass) { blocks.push(block('reportGet')); From 8ce648c10cb020728c17e0d13f3d4d14d9857181 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Sat, 7 Sep 2024 18:53:37 +0000 Subject: [PATCH 129/132] commit --- src/objects.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objects.js b/src/objects.js index ac229f501a..dd48777990 100644 --- a/src/objects.js +++ b/src/objects.js @@ -2352,13 +2352,13 @@ SpriteMorph.prototype.primitiveBlocks = function () { JsCallMethod: { type: 'reporter', code: 'callMethod', - spec: '%anyBlock $[ %anyBlock $]( %staticmult )', + spec: '%anyBlock $[ %anyBlock $]( %staticmult $)', category: 'control' }, JsRunMethod: { type: 'command', code: 'RunMethod', - spec: '%anyBlock $[ %anyBlock $]( %staticmult )', + spec: '%anyBlock $[ %anyBlock $]( %staticmult $)', category: 'control' } }; From 0408e76bbb12bc668744a9cbb39bb67c6cb44e0c Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 30 Oct 2024 02:30:42 +0000 Subject: [PATCH 130/132] commit --- src/blocks.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/blocks.js b/src/blocks.js index 20f5a1005c..8133769734 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -2682,6 +2682,8 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic, target) { ); return menu; }; + } else if (value instanceof Array) { + return this.showBubble(new List(value)) } else { // shorten the string, commented out because we now scroll it // txt = value.length > 500 ? value.slice(0, 500) + '...' : value; From 5dfbb4a8f115a72ae67f1c8ff629bdf4921f0e76 Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 30 Oct 2024 02:52:08 +0000 Subject: [PATCH 131/132] commit --- src/blocks.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/blocks.js b/src/blocks.js index 8133769734..7febc8cc7f 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -2683,7 +2683,9 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic, target) { return menu; }; } else if (value instanceof Array) { - return this.showBubble(new List(value)) + return this.showBubble(new ListWatcherMorph(new List(value))) + } else if (value instanceof Map) { + return this.showBubble(new ListWatcherMorph(new List(value.entries().map((v)=>new List(v))))) } else { // shorten the string, commented out because we now scroll it // txt = value.length > 500 ? value.slice(0, 500) + '...' : value; From b274289442e6d05681aa35d4774a498740c32fda Mon Sep 17 00:00:00 2001 From: "Ashton(tripple blocked, owns illendo)" <162846629+YeesterPlus@users.noreply.github.com> Date: Wed, 30 Oct 2024 03:06:21 +0000 Subject: [PATCH 132/132] commit --- src/blocks.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/blocks.js b/src/blocks.js index 7febc8cc7f..6fe01944d6 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -2683,9 +2683,19 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic, target) { return menu; }; } else if (value instanceof Array) { - return this.showBubble(new ListWatcherMorph(new List(value))) + morphToShow = new ListWatcherMorph(new List(value)); + morphToShow.update(true); + morphToShow.step = value.update; + morphToShow.isDraggable = false; + morphToShow.expand(this.parentThatIsA(ScrollFrameMorph).extent()); + isClickable = true; } else if (value instanceof Map) { - return this.showBubble(new ListWatcherMorph(new List(value.entries().map((v)=>new List(v))))) + morphToShow = new ListWatcherMorph(new List(value.entries().map((v) => new List(v)))); + morphToShow.update(true); + morphToShow.step = value.update; + morphToShow.isDraggable = false; + morphToShow.expand(this.parentThatIsA(ScrollFrameMorph).extent()); + isClickable = true; } else { // shorten the string, commented out because we now scroll it // txt = value.length > 500 ? value.slice(0, 500) + '...' : value;