Skip to content

Commit

Permalink
added "say" commands to the stage's palette
Browse files Browse the repository at this point in the history
  • Loading branch information
jmoenig committed Nov 29, 2023
1 parent 16ba418 commit e7168e8
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 20 deletions.
4 changes: 4 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* new 'text' list conversion selector, recursively joins all text and number leaf elements with spaces in between, filtering out and ignoring whitespace
* added "write" command to the stage's PEN primitives palette - prints text in proportional font at specified size wrapping lines "scrolling" to the end
* added "min", "max" and "atan2" reporters to the OPERATORS palette
* added "say" commands to the stage's palette
* **Notable Changes:**
* "reshape" now treats zero-ish (0, "", false) values in its dimension input as place-holders to accomodate the whole source list
* updated "Just Words" library for the new "text" list selector
Expand All @@ -15,6 +16,9 @@
* **Translation Updates:**
* German

2023-11-29
* objects, threads, scenes: added "say" commands to the stage's palette

2023-11-27
* objects: tweaked "write" primitive for the stage
* updated "Just Words" libary with a new version of the "sentence" reporter
Expand Down
6 changes: 3 additions & 3 deletions snap.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
<script src="src/symbols.js?version=2023-07-13"></script>
<script src="src/widgets.js?version=2023-05-24"></script>
<script src="src/blocks.js?version=2023-11-24"></script>
<script src="src/threads.js?version=2023-10-22"></script>
<script src="src/objects.js?version=2023-11-27"></script>
<script src="src/scenes.js?version=2022-10-25"></script>
<script src="src/threads.js?version=2023-10-29"></script>
<script src="src/objects.js?version=2023-11-29"></script>
<script src="src/scenes.js?version=2022-10-29"></script>
<script src="src/gui.js?version=2023-11-23"></script>
<script src="src/paint.js?version=2023-05-24"></script>
<script src="src/lists.js?version=2023-07-24"></script>
Expand Down
136 changes: 124 additions & 12 deletions src/objects.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
StagePickerMorph
SpeechBubbleMorph*
SpriteBubbleMorph
StageBubbleMorph
* defined in Morphic.js
Expand Down Expand Up @@ -94,11 +95,12 @@ embedMetadataPNG, SnapExtensions, SnapSerializer, snapEquals*/

/*jshint esversion: 11*/

modules.objects = '2023-November-27';
modules.objects = '2023-November-29';

var SpriteMorph;
var StageMorph;
var SpriteBubbleMorph;
var StageBubbleMorph;
var Costume;
var SVG_Costume;
var CostumeEditorMorph;
Expand Down Expand Up @@ -362,14 +364,12 @@ SpriteMorph.prototype.initBlocks = function () {
defaults: [['current'], 100, 50]
},
doSayFor: {
only: SpriteMorph,
type: 'command',
category: 'looks',
spec: 'say %s for %n secs',
defaults: [localize('Hello!'), 2]
},
bubble: {
only: SpriteMorph,
type: 'command',
category: 'looks',
spec: 'say %s',
Expand Down Expand Up @@ -8675,6 +8675,13 @@ StageMorph.prototype.setScale = function (number) {
this.scale = number;
this.setExtent(this.dimensions.multiplyBy(number));

// first resize my speech balloon, if any
bubble = this.talkBubble();
if (bubble) {
bubble.setScale(number);
this.positionTalkBubble();
}

// now move and resize all children - sprites, bubbles, watchers etc..
this.children.forEach(morph => {
relativePos = morph.position().subtract(pos);
Expand Down Expand Up @@ -9574,6 +9581,9 @@ StageMorph.prototype.blockTemplates = function (
blocks.push(watcherToggle('getCostumeIdx'));
blocks.push(block('getCostumeIdx'));
blocks.push('-');
blocks.push(block('doSayFor'));
blocks.push(block('bubble'));
blocks.push('-');
blocks.push(block('reportGetImageAttribute'));
blocks.push(block('reportNewCostumeStretched'));
blocks.push(block('reportNewCostume'));
Expand Down Expand Up @@ -10387,6 +10397,30 @@ StageMorph.prototype.changeEffect
StageMorph.prototype.clearEffects
= SpriteMorph.prototype.clearEffects;

// StageMorph talk bubble

StageMorph.prototype.stopTalking = SpriteMorph.prototype.stopTalking;

StageMorph.prototype.bubble = function (data) {
var bubble;
this.stopTalking();
if (data === '' || isNil(data)) {return; }
bubble = new StageBubbleMorph(data, this);
this.add(bubble);
this.positionTalkBubble();
};

StageMorph.prototype.talkBubble = SpriteMorph.prototype.talkBubble;

StageMorph.prototype.positionTalkBubble = function () {
var bubble = this.talkBubble();
if (!bubble) {return null; }
bubble.show();
bubble.keepWithin(this);
};

StageMorph.prototype.doThink = StageMorph.prototype.bubble;

// StageMorph sound management

StageMorph.prototype.addSound
Expand Down Expand Up @@ -10931,9 +10965,11 @@ SpriteBubbleMorph.prototype.init = function (
this.bubbleFontColor = BLACK;
this.bubbleFontSize = sprite.bubbleFontSize;
this.bubbleFontIsBold = sprite.bubbleFontIsBold;
this.bubbleFontAlignment = 'center';
this.bubbleCorner = sprite.bubbleCorner;
this.bubbleBorder = sprite.bubbleBorder;
this.bubblePadding = this.bubbleCorner / 2;
this.maxTextWidth = sprite.bubbleMaxTextWidth;

SpriteBubbleMorph.uber.init.call(
this,
Expand Down Expand Up @@ -10988,7 +11024,7 @@ SpriteBubbleMorph.prototype.dataAsMorph = function (data) {
null, // fontStyle
this.bubbleFontIsBold,
false, // italic
'center'
this.bubbleFontAlignment
);

// support exporting text / numbers directly from speech balloons:
Expand Down Expand Up @@ -11221,7 +11257,7 @@ SpriteBubbleMorph.prototype.dataAsMorph = function (data) {
sprite.bubbleCorner * 2 * this.scale
);
if (isText) {
width = Math.min(width, sprite.bubbleMaxTextWidth * this.scale);
width = Math.min(width, this.maxTextWidth * this.scale);
}
contents.color = this.bubbleFontColor;
contents.setWidth(width);
Expand Down Expand Up @@ -11267,13 +11303,7 @@ SpriteBubbleMorph.prototype.fixLayout = function () {
this.padding = this.bubblePadding * this.scale;

// adjust my dimensions
this.bounds.setWidth(this.contentsMorph.width()
+ (this.padding ? this.padding * 2 : this.edge * 2));
this.bounds.setHeight(this.contentsMorph.height()
+ this.edge
+ this.border * 2
+ this.padding * 2
+ 2);
this.adjustDimensions();

// position my contents
this.contentsMorph.setPosition(this.position().add(
Expand All @@ -11284,6 +11314,88 @@ SpriteBubbleMorph.prototype.fixLayout = function () {
));
};

SpriteBubbleMorph.prototype.adjustDimensions = function () {
this.bounds.setWidth(this.contentsMorph.width()
+ (this.padding ? this.padding * 2 : this.edge * 2));
this.bounds.setHeight(this.contentsMorph.height()
+ this.edge
+ this.border * 2
+ this.padding * 2
+ 2);
};

// StageBubbleMorph ////////////////////////////////////////////////////////

/*
I am a stage's scaleable speech bubble. I rely on SpriteMorph
for my preferences settings and quasi-inherit from SpriteBubbleMorph
*/

// StageBubbleMorph inherits from SpeechBubbleMorph:

StageBubbleMorph.prototype = new SpeechBubbleMorph();
StageBubbleMorph.prototype.constructor = StageBubbleMorph;
StageBubbleMorph.uber = SpeechBubbleMorph.prototype;

// StageBubbleMorph instance creation:

function StageBubbleMorph(data, stage) {
this.init(data, stage);
}

StageBubbleMorph.prototype.init = function (data, stage) {
var sprite = SpriteMorph.prototype;
this.stage = stage;
this.scale = stage ? stage.scale : 1;
this.data = data;
this.bubbleFontColor = BLACK;
this.bubbleFontSize = sprite.bubbleFontSize;
this.bubbleFontIsBold = false; // sprite.bubbleFontIsBold;
this.bubbleCorner = sprite.bubbleCorner;
this.bubbleBorder = sprite.bubbleBorder;
this.bubblePadding = this.bubbleCorner / 2;
this.maxTextWidth = stage.dimensions.x - sprite.bubbleCorner;
this.bubbleFontAlignment = 'left';

StageBubbleMorph.uber.init.call(
this,
this.data,
sprite.bubbleColor,
null,
null,
sprite.bubbleBorderColor,
null,
null, // isThought
true // no shadow
);

this.isCachingImage = true;
this.rerender();
};

// SpriteBubbleMorph contents formatting

StageBubbleMorph.prototype.dataAsMorph =
SpriteBubbleMorph.prototype.dataAsMorph;

// SpriteBubbleMorph scaling

StageBubbleMorph.prototype.setScale = SpriteBubbleMorph.prototype.setScale;

// SpriteBubbleMorph layout:

StageBubbleMorph.prototype.fixLayout = SpriteBubbleMorph.prototype.fixLayout;

StageBubbleMorph.prototype.adjustDimensions = function () {
this.bounds.setWidth(this.contentsMorph.width()
+ (this.padding ? this.padding * 2 : this.edge * 2));
this.bounds.setHeight(this.contentsMorph.height()
+ this.edge
+ this.border * 2);
};

StageBubbleMorph.prototype.outlinePath = BoxMorph.prototype.outlinePath;

// Costume /////////////////////////////////////////////////////////////

/*
Expand Down
3 changes: 2 additions & 1 deletion src/scenes.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ normalizeCanvas, SnapSerializer, Costume, ThreadManager, IDE_Morph*/

// Global stuff ////////////////////////////////////////////////////////

modules.scenes = '2022-October-25';
modules.scenes = '2022-November-29';

// Projecct /////////////////////////////////////////////////////////

Expand Down Expand Up @@ -244,6 +244,7 @@ Scene.prototype.stop = function (forGood) {
if (this.stage.projectionSource) {
this.stage.stopProjection();
}
this.stage.stopTalking();
this.stage.children.forEach(morph => {
if (morph.stopTalking) {
morph.stopTalking();
Expand Down
8 changes: 4 additions & 4 deletions src/threads.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ StagePickerMorph, CustomBlockDefinition, CommentMorph*/

/*jshint esversion: 11, bitwise: false, evil: true*/

modules.threads = '2023-November-22';
modules.threads = '2023-November-29';

var ThreadManager;
var Process;
Expand Down Expand Up @@ -4124,9 +4124,7 @@ Process.prototype.doAsk = function (data) {
);
if (!activePrompter) {
if (data instanceof List) {
if (!isStage) {
rcvr.stopTalking();
}
rcvr.stopTalking();
this.prompter = new StagePickerMorph(data);
this.prompter.createItems(stage.scale);
leftSpace = rcvr.left() - stage.left();
Expand All @@ -4152,6 +4150,8 @@ Process.prototype.doAsk = function (data) {
} else {
if (!isStage && !isHiddenSprite) {
rcvr.bubble(data, false, true);
} else if (isStage) {
rcvr.stopTalking();
}
this.prompter = new StagePrompterMorph(
isStage || isHiddenSprite ? data : null
Expand Down

0 comments on commit e7168e8

Please sign in to comment.