diff --git a/HISTORY.md b/HISTORY.md index cd59cf24..479e6d00 100755 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,9 @@ ## in development: +### 2020-07-17 +* morphic, blocks: blocks-fadeout (under construction) + ### 2020-07-15 * morphic: made keyboard handler (more) invisible, thanks, Bernat! * gui: made remaining synchronous http requests asynch (url: #open, #run) diff --git a/src/blocks.js b/src/blocks.js index e9b23692..3ac17879 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -65,6 +65,9 @@ BoxMorph* CommentMorph ScriptFocusMorph + StringMorph* + BlockLabelMorph + InputSlotStringMorph * from morphic.js @@ -75,6 +78,7 @@ defined. Use this list to locate code in this document: SyntaxElementMorph + BlockLabelMorph BlockMorph CommandBlockMorph HatBlockMorph @@ -86,6 +90,7 @@ RingCommandSlotMorph CSlotMorph InputSlotMorph + InputSlotStringMorph BooleanSlotMorph ArrowMorph TextSlotMorph @@ -142,16 +147,17 @@ document, getDocumentPositionOf, isNaN, isString, newCanvas, nop, parseFloat, radians, useBlurredShadows, SpeechBubbleMorph, modules, StageMorph, Sound, fontHeight, TableFrameMorph, SpriteMorph, Context, ListWatcherMorph, Rectangle, DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, WHITE, BLACK, -Costume, IDE_Morph, BlockDialogMorph, BlockEditorMorph, localize, isNil, +Costume, IDE_Morph, BlockDialogMorph, BlockEditorMorph, localize, isNil, CLEAR, isSnapObject, PushButtonMorph, SpriteIconMorph, Process, AlignmentMorph, CustomCommandBlockMorph, SymbolMorph, ToggleButtonMorph, DialMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2020-July-15'; +modules.blocks = '2020-July-17'; var SyntaxElementMorph; var BlockMorph; +var BlockLabelMorph; var CommandBlockMorph; var ReporterBlockMorph; var ScriptsMorph; @@ -159,6 +165,7 @@ var ArgMorph; var CommandSlotMorph; var CSlotMorph; var InputSlotMorph; +var InputSlotStringMorph; var BooleanSlotMorph; var ArrowMorph; var ColorSlotMorph; @@ -1770,7 +1777,7 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { ZERO : this.embossing; part.fixLayout(); } else { - part = new StringMorph( + part = new BlockLabelMorph( spec, // text this.fontSize, // fontSize this.labelFontStyle, // fontStyle @@ -1783,6 +1790,7 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { WHITE, // color this.labelFontName // fontName ); + } return part; }; @@ -2268,6 +2276,58 @@ SyntaxElementMorph.prototype.mappedCode = function (definitions) { return result; }; +// BlockLabelMorph /////////////////////////////////////////////// + +/* + I am a piece of single-line text written on a block. I serve as a + container for sharing typographic attributes among my instances +*/ + +// BlockLabelMorph inherits from StringMorph: + +BlockLabelMorph.prototype = new StringMorph(); +BlockLabelMorph.prototype.constructor = BlockLabelMorph; +BlockLabelMorph.uber = StringMorph.prototype; + +function BlockLabelMorph( + text, + fontSize, + fontStyle, + bold, + italic, + isNumeric, + shadowOffset, + shadowColor, + color, + fontName +) { + this.init( + text, + fontSize, + fontStyle, + bold, + italic, + isNumeric, + shadowOffset, + shadowColor, + color, + fontName + ); +} + +BlockLabelMorph.prototype.getRenderColor = function () { + if (MorphicPreferences.isFlat) { + return this.parent.alpha > 0.4 ? this.color + : (this.parent.alpha > 0.1 ? BLACK + : this.parent.color.solid()); + } + return this.parent.alpha > 0.1 ? this.color : this.parent.color.solid(); +}; + +BlockLabelMorph.prototype.getShadowRenderColor = function () { + return this.parent.alpha > 0.6 ? this.shadowColor : CLEAR; +}; + // BlockMorph ////////////////////////////////////////////////////////// /* @@ -4368,6 +4428,20 @@ BlockMorph.prototype.activeProcess = function () { return null; }; +BlockMorph.prototype.mouseEnterBounds = function () { + if (this.alpha < 1) { + this.alpha = Math.min(this.alpha + 0.2, 1); + this.rerender(); + } +}; + +BlockMorph.prototype.mouseLeaveBounds = function () { + if (SyntaxElementMorph.prototype.alpha < 1) { + delete this.alpha; + this.rerender(); + } +}; + // BlockMorph dragging and dropping BlockMorph.prototype.rootForGrab = function () { @@ -6439,6 +6513,15 @@ ScriptsMorph.prototype.fullCopy = function () { return cpy; }; +// ScriptsMorph rendering: + +ScriptsMorph.prototype.renderCachedTexture = function (ctx) { + // support blocks-to-text slider + if (SyntaxElementMorph.prototype.alpha > 0.8) { + ScriptsMorph.uber.renderCachedTexture.call(this, ctx); + } +}; + // ScriptsMorph stepping: ScriptsMorph.prototype.step = function () { @@ -8556,7 +8639,7 @@ InputSlotMorph.prototype.init = function ( choiceDict, isReadOnly ) { - var contents = new StringMorph(''), + var contents = new InputSlotStringMorph(''), arrow = new ArrowMorph( 'down', 0, @@ -9754,6 +9837,62 @@ InputSlotMorph.prototype.drawRoundBorder = function (ctx) { ctx.stroke(); }; +// InputSlotStringMorph /////////////////////////////////////////////// + +/* + I am a piece of single-line text inside an input slot block. I serve as a + container for sharing typographic attributes among my instances +*/ + +// InputSlotStringMorph inherits from StringMorph: + +InputSlotStringMorph.prototype = new StringMorph(); +InputSlotStringMorph.prototype.constructor = InputSlotStringMorph; +InputSlotStringMorph.uber = StringMorph.prototype; + +function InputSlotStringMorph( + text, + fontSize, + fontStyle, + bold, + italic, + isNumeric, + shadowOffset, + shadowColor, + color, + fontName +) { + this.init( + text, + fontSize, + fontStyle, + bold, + italic, + isNumeric, + shadowOffset, + shadowColor, + color, + fontName + ); +} + +InputSlotStringMorph.prototype.getRenderColor = function () { + if (MorphicPreferences.isFlat) { + if (this.isEditable) { + return this.color; + } + return this.parent.alpha > 0.4 ? this.color : BLACK; + } + if (this.isEditable) { + return this.parent.alpha > 0.3 ? this.color : WHITE; + } + return this.color; +}; + +InputSlotStringMorph.prototype.getShadowRenderColor = function () { + return this.parent.alpha > 0.6 ? this.shadowColor : CLEAR; +}; + // TemplateSlotMorph /////////////////////////////////////////////////// /* diff --git a/src/gui.js b/src/gui.js index d530b80c..057d42fd 100644 --- a/src/gui.js +++ b/src/gui.js @@ -78,7 +78,7 @@ Animation, BoxMorph, BlockEditorMorph, BlockDialogMorph, Note, ZERO, BLACK*/ // Global stuff //////////////////////////////////////////////////////// -modules.gui = '2020-July-16'; +modules.gui = '2020-July-17'; // Declarations @@ -3143,7 +3143,7 @@ IDE_Morph.prototype.settingsMenu = function () { alpha => { SyntaxElementMorph.prototype.setAlphaScaled(alpha); this.rerender(); - }, + } ); }, 'set the blocks\'\nalpha value', diff --git a/src/morphic.js b/src/morphic.js index 7928cf7b..f2195de7 100644 --- a/src/morphic.js +++ b/src/morphic.js @@ -471,6 +471,8 @@ mouseLeave mouseEnterDragging mouseLeaveDragging + mouseEnterBounds + mouseLeaveBounds mouseMove mouseScroll @@ -1276,13 +1278,14 @@ /*global window, HTMLCanvasElement, FileReader, Audio, FileList, Map*/ -var morphicVersion = '2020-July-16'; +var morphicVersion = '2020-July-17'; var modules = {}; // keep track of additional loaded modules var useBlurredShadows = true; const ZERO = new Point(); const BLACK = new Color(); const WHITE = new Color(255, 255, 255); +const CLEAR = new Color(0, 0, 0, 0); Object.freeze(ZERO); Object.freeze(BLACK); @@ -2304,6 +2307,14 @@ Color.prototype.inverted = function () { ); }; +Color.prototype.solid = function () { + return new Color( + this.r, + this.g, + this.b + ); +}; + // Points ////////////////////////////////////////////////////////////// // Point instance creation: @@ -8507,6 +8518,16 @@ StringMorph.prototype.font = function () { this.fontStyle; }; +StringMorph.prototype.getRenderColor = function () { + // answer the rendering color, can be overridden for my children + return this.color; +}; + +StringMorph.prototype.getShadowRenderColor = function () { + // answer the shadow rendering color, can be overridden for my children + return this.shadowColor; +}; + StringMorph.prototype.fixLayout = function (justMe) { // determine my extent depending on my current settings var width, @@ -8537,6 +8558,7 @@ StringMorph.prototype.fixLayout = function (justMe) { StringMorph.prototype.render = function (ctx) { var start, stop, i, p, c, x, y, shadowOffset = this.shadowOffset || ZERO, + shadowColor = this.getShadowRenderColor(), txt = this.isPassword ? this.password('*', this.text.length) : this.text; @@ -8546,17 +8568,17 @@ StringMorph.prototype.render = function (ctx) { ctx.textBaseline = 'bottom'; // first draw the shadow, if any - if (this.shadowColor) { + if (shadowColor) { x = Math.max(shadowOffset.x, 0); y = Math.max(shadowOffset.y, 0); - ctx.fillStyle = this.shadowColor.toString(); + ctx.fillStyle = shadowColor.toString(); ctx.fillText(txt, x, fontHeight(this.fontSize) + y); } // now draw the actual text x = Math.abs(Math.min(shadowOffset.x, 0)); y = Math.abs(Math.min(shadowOffset.y, 0)); - ctx.fillStyle = this.color.toString(); + ctx.fillStyle = this.getRenderColor().toString(); if (this.isShowingBlanks) { this.renderWithBlanks( @@ -8615,7 +8637,7 @@ StringMorph.prototype.renderWithBlanks = function (ctx, startX, y) { } isFirst = false; if (word !== '') { - ctx.fillStyle = this.color.toString(); + ctx.fillStyle = this.getRenderColor().toString(); ctx.fillText(word, x, y); x += ctx.measureText(word).width; } @@ -9268,6 +9290,7 @@ TextMorph.prototype.fixLayout = function () { TextMorph.prototype.render = function (ctx) { var shadowWidth = Math.abs(this.shadowOffset.x), shadowHeight = Math.abs(this.shadowOffset.y), + shadowColor = this.getShadowRenderColor(), i, line, width, offx, offy, x, y, start, stop, p, c; // prepare context for drawing text @@ -9282,10 +9305,10 @@ TextMorph.prototype.render = function (ctx) { } // draw the shadow, if any - if (this.shadowColor) { + if (shadowColor) { offx = Math.max(this.shadowOffset.x, 0); offy = Math.max(this.shadowOffset.y, 0); - ctx.fillStyle = this.shadowColor.toString(); + ctx.fillStyle = shadowColor.toString(); for (i = 0; i < this.lines.length; i = i + 1) { line = this.lines[i]; @@ -9306,7 +9329,7 @@ TextMorph.prototype.render = function (ctx) { // now draw the actual text offx = Math.abs(Math.min(this.shadowOffset.x, 0)); offy = Math.abs(Math.min(this.shadowOffset.y, 0)); - ctx.fillStyle = this.color.toString(); + ctx.fillStyle = this.getRenderColor().toString(); for (i = 0; i < this.lines.length; i = i + 1) { line = this.lines[i]; @@ -9336,6 +9359,11 @@ TextMorph.prototype.render = function (ctx) { } }; +TextMorph.prototype.getRenderColor = StringMorph.prototype.getRenderColor; + +TextMorph.prototype.getShadowRenderColor = + StringMorph.prototype.getShadowRenderColor; + TextMorph.prototype.setExtent = function (aPoint) { this.maxWidth = Math.max(aPoint.x, 0); this.changed(); @@ -11066,6 +11094,7 @@ HandMorph.prototype.init = function (aWorld) { this.world = aWorld; this.mouseButton = null; this.mouseOverList = []; + this.mouseOverBounds = []; this.morphToGrab = null; this.grabPosition = null; this.grabOrigin = null; @@ -11240,6 +11269,8 @@ HandMorph.prototype.drop = function () { mouseLeave mouseEnterDragging mouseLeaveDragging + mouseEnterBounds + mouseLeaveBounds mouseMove mouseScroll */ @@ -11385,6 +11416,7 @@ HandMorph.prototype.processMouseMove = function (event) { var pos, posInDocument = getDocumentPositionOf(this.world.worldCanvas), mouseOverNew, + mouseOverBoundsNew, morph, topMorph; @@ -11396,7 +11428,7 @@ HandMorph.prototype.processMouseMove = function (event) { this.setPosition(pos); // determine the new mouse-over-list: - // mouseOverNew = this.allMorphsAtPointer(); + mouseOverBoundsNew = this.allMorphsAtPointer(); mouseOverNew = this.morphAtPointer().allParents(); if (!this.children.length && this.mouseButton) { @@ -11434,6 +11466,21 @@ HandMorph.prototype.processMouseMove = function (event) { } } + this.mouseOverBounds.forEach(old => { + if (!contains(mouseOverBoundsNew, old)) { + if (old.mouseLeaveBounds) { + old.mouseLeaveBounds(); + } + } + }); + mouseOverBoundsNew.forEach(newMorph => { + if (!contains(this.mouseOverBounds, newMorph)) { + if (newMorph.mouseEnterBounds) { + newMorph.mouseEnterBounds(); + } + } + }); + this.mouseOverList.forEach(old => { if (!contains(mouseOverNew, old)) { if (old.mouseLeave) { @@ -11471,6 +11518,7 @@ HandMorph.prototype.processMouseMove = function (event) { } }); this.mouseOverList = mouseOverNew; + this.mouseOverBounds = mouseOverBoundsNew; }; HandMorph.prototype.processMouseScroll = function (event) {