Fix hide/show

This commit is contained in:
Paul Kaplan 2017-10-06 15:24:29 -04:00
parent 14600d7893
commit 9af9eb1d92

View file

@ -1,6 +1,5 @@
const Cast = require('../util/cast'); const Cast = require('../util/cast');
const Clone = require('../util/clone'); const Clone = require('../util/clone');
const Runtime = require('../engine/runtime');
const RenderedTarget = require('../sprites/rendered-target'); const RenderedTarget = require('../sprites/rendered-target');
/** /**
@ -9,6 +8,7 @@ const RenderedTarget = require('../sprites/rendered-target');
* @property {?int} drawableId - the ID of the associated bubble Drawable, null if none. * @property {?int} drawableId - the ID of the associated bubble Drawable, null if none.
* @property {string} text - the text of the bubble. * @property {string} text - the text of the bubble.
* @property {string} type - the type of the bubble, "say" or "think" * @property {string} type - the type of the bubble, "say" or "think"
* @property {Boolean} visible - whether the bubble is hidden along with its sprite.
*/ */
class Scratch3LooksBlocks { class Scratch3LooksBlocks {
@ -65,15 +65,6 @@ class Scratch3LooksBlocks {
return bubbleState; return bubbleState;
} }
/**
* @param {Target} target - collect bubble state for this target. Probably, but not necessarily, a RenderedTarget.
* @private
*/
_resetBubbleState (target) {
const defaultBubbleState = Clone.simple(Scratch3LooksBlocks.DEFAULT_BUBBLE_STATE);
target.setCustomState(Scratch3LooksBlocks.STATE_KEY, defaultBubbleState);
}
/** /**
* Handle a target which has moved. * Handle a target which has moved.
* @param {RenderedTarget} target - the target which has moved. * @param {RenderedTarget} target - the target which has moved.
@ -81,27 +72,26 @@ class Scratch3LooksBlocks {
*/ */
_onTargetMoved (target) { _onTargetMoved (target) {
const bubbleState = this._getBubbleState(target); const bubbleState = this._getBubbleState(target);
if (bubbleState.drawableId && bubbleState.visible) { if (bubbleState.drawableId && bubbleState.visible) {
this._checkBubbleBounds(target);
this._positionBubble(target); this._positionBubble(target);
} }
} }
/** /**
* Handle a target which has moved. * Handle a target which is exiting.
* @param {RenderedTarget} target - the target which has moved. * @param {RenderedTarget} target - the target.
* @private * @private
*/ */
_onTargetWillExit (target) { _onTargetWillExit (target) {
const bubbleState = this._getBubbleState(target); const bubbleState = this._getBubbleState(target);
if (bubbleState.drawableId) { if (bubbleState.drawableId) {
this.runtime.renderer.destroyDrawable(bubbleState.drawableId); this.runtime.renderer.destroyDrawable(bubbleState.drawableId);
bubbleState.drawableId = null;
} }
if (bubbleState.skinId) { if (bubbleState.skinId) {
this.runtime.renderer.destroySkin(bubbleState.skinId); this.runtime.renderer.destroySkin(bubbleState.skinId);
bubbleState.skinId = null;
} }
} }
/** /**
@ -110,16 +100,12 @@ class Scratch3LooksBlocks {
*/ */
_onResetBubbles () { _onResetBubbles () {
for (let n = 0; n < this.runtime.targets.length; n++) { for (let n = 0; n < this.runtime.targets.length; n++) {
const target = this.runtime.targets[n]; this._onTargetWillExit(this.runtime.targets[n]);
const bubbleState = this._getBubbleState(target);
if (bubbleState.drawableId) {
this._clearBubble(target);
}
} }
} }
/** /**
* Position the bubble of a target. * Position the bubble of a target. If it doesn't fit on the specified side, flip and rerender.
* @param {!Target} target Target whose bubble needs positioning. * @param {!Target} target Target whose bubble needs positioning.
* @private * @private
*/ */
@ -128,34 +114,20 @@ class Scratch3LooksBlocks {
const [bubbleWidth, bubbleHeight] = this.runtime.renderer.getSkinSize(bubbleState.drawableId); const [bubbleWidth, bubbleHeight] = this.runtime.renderer.getSkinSize(bubbleState.drawableId);
const targetBounds = target.getBounds(); const targetBounds = target.getBounds();
const stageBounds = this.runtime.getTargetForStage().getBounds(); const stageBounds = this.runtime.getTargetForStage().getBounds();
this.runtime.renderer.updateDrawableProperties(bubbleState.drawableId, {
position: [
bubbleState.onSpriteRight ? targetBounds.right : targetBounds.left - bubbleWidth,
Math.min(stageBounds.top, targetBounds.top + bubbleHeight)
]
});
this.runtime.requestRedraw();
}
/**
* Check whether a bubble needs to be flipped. If so, flip the `onSpriteRight` state
* and call the bubble render again.
* @param {!Target} target Target whose bubble needs positioning.
* @private
*/
_checkBubbleBounds (target) {
const bubbleState = this._getBubbleState(target);
const [bubbleWidth, _] = this.runtime.renderer.getSkinSize(bubbleState.drawableId);
const targetBounds = target.getBounds();
const stageBounds = this.runtime.getTargetForStage().getBounds();
if (bubbleState.onSpriteRight && bubbleWidth + targetBounds.right > stageBounds.right) { if (bubbleState.onSpriteRight && bubbleWidth + targetBounds.right > stageBounds.right) {
bubbleState.onSpriteRight = false; bubbleState.onSpriteRight = false;
this._renderBubble(target); this._renderBubble(target);
} else if (!bubbleState.onSpriteRight && targetBounds.left - bubbleWidth < stageBounds.left) { } else if (!bubbleState.onSpriteRight && targetBounds.left - bubbleWidth < stageBounds.left) {
bubbleState.onSpriteRight = true; bubbleState.onSpriteRight = true;
this._renderBubble(target); this._renderBubble(target);
} else {
this.runtime.renderer.updateDrawableProperties(bubbleState.drawableId, {
position: [
bubbleState.onSpriteRight ? targetBounds.right : targetBounds.left - bubbleWidth,
Math.min(stageBounds.top, targetBounds.top + bubbleHeight)
]
});
this.runtime.requestRedraw();
} }
} }
@ -164,11 +136,15 @@ class Scratch3LooksBlocks {
* just set it to visible and update the type/text. Otherwise create a new * just set it to visible and update the type/text. Otherwise create a new
* bubble and update the relevant custom state. * bubble and update the relevant custom state.
* @param {!Target} target Target who needs a bubble. * @param {!Target} target Target who needs a bubble.
* @return {undefined} Early return if text is empty string.
* @private * @private
*/ */
_renderBubble (target) { _renderBubble (target) {
const bubbleState = this._getBubbleState(target); const bubbleState = this._getBubbleState(target);
const {type, text, onSpriteRight} = bubbleState; const {type, text, onSpriteRight} = bubbleState;
if (text === '') {
return this._setBubbleVisibility(target, false);
}
if (bubbleState.skinId) { if (bubbleState.skinId) {
if (!bubbleState.visible) { if (!bubbleState.visible) {
@ -195,8 +171,6 @@ class Scratch3LooksBlocks {
this.runtime.renderer.updateDrawableProperties(bubbleState.drawableId, { this.runtime.renderer.updateDrawableProperties(bubbleState.drawableId, {
skinId: bubbleState.skinId skinId: bubbleState.skinId
}); });
this._checkBubbleBounds(target);
} }
this._positionBubble(target); this._positionBubble(target);
@ -211,24 +185,21 @@ class Scratch3LooksBlocks {
* @private * @private
*/ */
_updateBubble (target, type, text) { _updateBubble (target, type, text) {
if (text === '') { const bubbleState = this._getBubbleState(target);
this._clearBubble(target); bubbleState.type = type;
} else { bubbleState.text = text;
const bubbleState = this._getBubbleState(target); this._renderBubble(target);
bubbleState.type = type;
bubbleState.text = text;
this._renderBubble(target);
}
} }
/** /**
* Hide the bubble for a given target. * Hide the bubble for a given target.
* @param {!Target} target Target that say/think blocks are being called on. * @param {!Target} target Target that say/think blocks are being called on.
* @param {!boolean} visibility Visible or not.
* @private * @private
*/ */
_clearBubble (target) { _setBubbleVisibility (target, visibility) {
const bubbleState = this._getBubbleState(target); const bubbleState = this._getBubbleState(target);
bubbleState.visible = false; bubbleState.visible = visibility;
if (bubbleState.drawableId) { if (bubbleState.drawableId) {
this.runtime.renderer.updateDrawableProperties(bubbleState.drawableId, { this.runtime.renderer.updateDrawableProperties(bubbleState.drawableId, {
visible: bubbleState.visible visible: bubbleState.visible
@ -278,7 +249,7 @@ class Scratch3LooksBlocks {
return new Promise(resolve => { return new Promise(resolve => {
setTimeout(() => { setTimeout(() => {
// Clear say bubble and proceed. // Clear say bubble and proceed.
this._clearBubble(util.target); this._updateBubble(util.target, 'say', '');
resolve(); resolve();
}, 1000 * args.SECS); }, 1000 * args.SECS);
}); });
@ -293,7 +264,7 @@ class Scratch3LooksBlocks {
return new Promise(resolve => { return new Promise(resolve => {
setTimeout(() => { setTimeout(() => {
// Clear say bubble and proceed. // Clear say bubble and proceed.
this._clearBubble(util.target); this._updateBubble(util.target, 'think', '');
resolve(); resolve();
}, 1000 * args.SECS); }, 1000 * args.SECS);
}); });
@ -301,10 +272,12 @@ class Scratch3LooksBlocks {
show (args, util) { show (args, util) {
util.target.setVisible(true); util.target.setVisible(true);
this._renderBubble(util.target);
} }
hide (args, util) { hide (args, util) {
util.target.setVisible(false); util.target.setVisible(false);
this._setBubbleVisibility(util.target, false);
} }
/** /**