Skip to content

Commit 8ee8bb5

Browse files
authored
Addition of lyrics through phase maker (#4174)
* No clear space * Lyrics row in Phrase Maker * Addition of lyric row in phrase maker widget * update 2 * update 3 * final * formatting fix * fix 2 * final fix * lyrics row fixes * trailling space deleted * lyricsON is global * features added
1 parent 340a1d0 commit 8ee8bb5

File tree

4 files changed

+156
-15
lines changed

4 files changed

+156
-15
lines changed

js/activity.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,9 @@ class Activity {
269269
// Flag to check if the helpful search widget is active or not (for "click" event handler purpose)
270270
this.isHelpfulSearchWidgetOn = false;
271271

272+
//Flag to check if any other input box is active or not
273+
this.isInputON = false;
274+
272275
this.beginnerMode = true;
273276
try {
274277
if (this.storage.beginnerMode === undefined) {
@@ -2698,6 +2701,7 @@ class Activity {
26982701
docById("lilypondModal").style.display === "block" ||
26992702
this.searchWidget.style.visibility === "visible" ||
27002703
this.helpfulSearchWidget.style.visibility === "visible" ||
2704+
this.isInputON ||
27012705
docById("planet-iframe").style.display === "" ||
27022706
docById("paste").style.visibility === "visible" ||
27032707
docById("wheelDiv").style.display === "" ||

js/blocks/ExtrasBlocks.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,8 @@ function setupExtrasBlocks(activity) {
508508
logo.oscilloscopeTurtles.indexOf(activity.turtles.turtleList[turtleIndex]) < 0
509509
)
510510
logo.oscilloscopeTurtles.push(activity.turtles.turtleList[turtleIndex]);
511+
} else if (logo.inMatrix) {
512+
logo.phraseMaker.lyricsON = true;
511513
} else if (!logo.inStatusMatrix) {
512514
if (args.length === 1) {
513515
if (args[0] !== null) {

js/blocks/WidgetBlocks.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,6 +1430,7 @@ function setupWidgetBlocks(activity) {
14301430
logo.phraseMaker.rowArgs = [];
14311431
logo.phraseMaker.graphicsBlocks = [];
14321432
logo.phraseMaker.clearBlocks();
1433+
logo.phraseMaker.lyricsON = false;
14331434

14341435
logo.tupletRhythms = [];
14351436
logo.tupletParams = [];

js/widgets/phrasemaker.js

Lines changed: 149 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,19 @@ class PhraseMaker {
250250
this.notesBlockMap = [];
251251
this._blockMapHelper = [];
252252
this.columnBlocksMap = [];
253+
254+
/**
255+
* Stores lyrics for each column.
256+
* @type {Array<string>}
257+
* @private
258+
*/
259+
this._lyrics = [];
260+
261+
/**
262+
* Marks the presence of print block
263+
* @type {boolean}
264+
*/
265+
this.lyricsON = false;
253266
}
254267

255268
/**
@@ -280,7 +293,7 @@ class PhraseMaker {
280293
* @type {NodeListOf<Element>}
281294
*/
282295
var windowFrameElements = floatingWindowsDiv.querySelectorAll(".windowFrame");
283-
296+
284297
for (var i = 0; i < windowFrameElements.length; i++) {
285298

286299
/**
@@ -324,7 +337,7 @@ class PhraseMaker {
324337
* @type {number}
325338
*/
326339
var maxHeight = screenHeight * 0.8;
327-
340+
328341
if (totalWidth > screenWidth || totalHeight > screenHeight) {
329342
windowFrame.style.height = Math.min(totalHeight, maxHeight) + "px";
330343
windowFrame.style.width = Math.min(totalWidth, maxWidth) + "px";
@@ -343,7 +356,7 @@ class PhraseMaker {
343356
}
344357
}
345358
}
346-
359+
347360
/**
348361
* Clears block references within the PhraseMaker.
349362
* Resets arrays used to track row and column blocks.
@@ -503,7 +516,6 @@ class PhraseMaker {
503516
this._stopOrCloseClicked = true;
504517
this.activity.hideMsgs();
505518
docById("wheelDivptm").style.display = "none";
506-
507519
widgetWindow.destroy();
508520
};
509521

@@ -625,7 +637,8 @@ class PhraseMaker {
625637
drumName = getDrumName(this.rowLabels[i]);
626638

627639
// Depending on the row, we choose a different background color.
628-
if (
640+
if (this.rowLabels[i] === "print") break;
641+
else if (
629642
MATRIXGRAPHICS.indexOf(this.rowLabels[i]) != -1 ||
630643
MATRIXGRAPHICS2.indexOf(this.rowLabels[i]) != -1
631644
) {
@@ -652,7 +665,8 @@ class PhraseMaker {
652665
cell.innerHTML = "";
653666
this._headcols[i] = cell;
654667

655-
if (drumName != null) {
668+
if (this.rowLabels[i] === "print") break;
669+
else if (drumName != null) {
656670
cell.innerHTML =
657671
'&nbsp;&nbsp;<img src="' +
658672
getDrumIcon(drumName) +
@@ -757,7 +771,8 @@ class PhraseMaker {
757771
cell.setAttribute("alt", i);
758772
this._labelcols[i] = cell;
759773

760-
if (drumName != null) {
774+
if (this.rowLabels[i] === "print") break;
775+
else if (drumName != null) {
761776
cell.innerHTML = _(drumName);
762777
cell.style.fontSize = Math.floor(this._cellScale * 14) + "px";
763778
cell.setAttribute("alt", i + "__" + "drumblocks");
@@ -913,6 +928,82 @@ class PhraseMaker {
913928
j += 1;
914929
}
915930

931+
// Add a row for lyrics if they are enabled in the ExtraBlocks.js
932+
if (this.lyricsON) {
933+
934+
const lyricsRow = ptmTable.insertRow();
935+
lyricsRow.setAttribute("id", "lyricRow");
936+
lyricsRow.style.position = "sticky";
937+
938+
// Label Cell (Fixed like "note value")
939+
cell = lyricsRow.insertCell();
940+
cell.setAttribute("colspan", "2");
941+
cell.className = "headcol";
942+
cell.style.position = "sticky";
943+
cell.style.left = "1.2px";
944+
cell.style.zIndex = "1";
945+
cell.style.backgroundColor = platformColor.lyricsLabelBackground || "#FF2B77";
946+
cell.style.textAlign = "center";
947+
cell.innerHTML = "Lyrics";
948+
949+
// Nested Table for Input Fields
950+
tempTable = document.createElement("table");
951+
tempTable.setAttribute("cellpadding", "0px");
952+
const inputRow = tempTable.insertRow();
953+
954+
// Add input cells for lyrics
955+
if (!this._lyrics || this._lyrics.length === 0) {
956+
this._lyrics = Array(this.activity.logo.tupletRhythms.length).fill("");
957+
} else if (this.activity.logo.tupletRhythms.length > this._lyrics.length) {
958+
const additionalLength = this.activity.logo.tupletRhythms.length - this._lyrics.length;
959+
this._lyrics = this._lyrics.concat(Array(additionalLength).fill(""));
960+
}
961+
for (let i = 0; i < this.activity.logo.tupletRhythms.length; i++) {
962+
const noteValue = this.activity.logo.tupletRhythms[i][2];
963+
const inputCell = inputRow.insertCell();
964+
inputCell.style.height = Math.floor(MATRIXSOLFEHEIGHT * this._cellScale) + 1 + "px";
965+
inputCell.style.width = this._noteWidth(noteValue) + "px";
966+
inputCell.style.minWidth = inputCell.style.width;
967+
inputCell.style.maxWidth = inputCell.style.width;
968+
inputCell.style.backgroundColor = "#FF6EA1";
969+
inputCell.style.fontFamily = "sans-serif";
970+
inputCell.style.cursor = "default";
971+
inputCell.style.borderSpacing = "1px 1px";
972+
inputCell.style.borderCollapse = "collapse";
973+
inputCell.style.boxSizing = "border-box";
974+
inputCell.style.padding = "0";
975+
inputCell.style.borderRadius = "6px";
976+
inputCell.style.border = "none";
977+
inputCell.setAttribute("alt", i + "__" + "graphicsblocks2");
978+
979+
const lyricsInput = document.createElement("input");
980+
lyricsInput.type = "text";
981+
lyricsInput.value = this._lyrics[i];
982+
983+
lyricsInput.style.height = inputCell.style.height;
984+
lyricsInput.style.width = "100%";
985+
lyricsInput.style.minWidth = inputCell.style.minWidth;
986+
lyricsInput.style.maxWidth = inputCell.style.maxWidth;
987+
lyricsInput.style.fontSize = "inherit";
988+
lyricsInput.style.fontFamily = "sans-serif";
989+
lyricsInput.style.cursor = "default";
990+
lyricsInput.style.boxSizing = "border-box";
991+
lyricsInput.style.padding = "0";
992+
lyricsInput.style.border = "none";
993+
lyricsInput.style.borderRadius = "6px";
994+
lyricsInput.style.backgroundColor = "#FF6EA1";
995+
996+
inputCell.appendChild(lyricsInput);
997+
lyricsInput.addEventListener("focus", () => this.activity.isInputON = true);
998+
lyricsInput.addEventListener("blur", () => this.activity.isInputON = false);
999+
lyricsInput.addEventListener("input", (event) => {
1000+
this._lyrics[i] = event.target.value;
1001+
});
1002+
1003+
};
1004+
lyricsRow.insertCell().appendChild(tempTable);
1005+
}
1006+
9161007
// An extra row for the note and tuplet values
9171008
ptmTableRow = ptmTable.insertRow();
9181009
ptmCell = ptmTableRow.insertCell();
@@ -953,6 +1044,7 @@ class PhraseMaker {
9531044
tempTable = document.createElement("table");
9541045
tempTable.setAttribute("cellpadding", "0px");
9551046
this._tupletNoteValueRow = tempTable.insertRow();
1047+
const tempTable2 = tempTable;
9561048
this._tupletValueRow = tempTable.insertRow();
9571049
this._noteValueRow = tempTable.insertRow();
9581050
ptmTableRow.insertCell().append(tempTable);
@@ -3464,7 +3556,7 @@ class PhraseMaker {
34643556
this._restartGrid.call(this);
34653557
}
34663558

3467-
3559+
34683560
/**
34693561
* Deletes a note from the grid and readjusts the notes accordingly.
34703562
* @param {number} noteToDivide - The index of the note to delete.
@@ -4507,6 +4599,10 @@ class PhraseMaker {
45074599
* @param {number} noteCounter - The current note index in the playback sequence.
45084600
*/
45094601
__playNote(time, noteCounter) {
4602+
// Show lyrics while playing notes.
4603+
if (this.lyricsON) {
4604+
this.activity.textMsg(this._lyrics[noteCounter]);
4605+
}
45104606
// If the widget is closed, stop playing.
45114607
if (!this.widgetWindow.isVisible()) {
45124608
return;
@@ -4879,7 +4975,16 @@ class PhraseMaker {
48794975
* @private
48804976
*/
48814977
_clear() {
4882-
// 'Unclick' every entry in the matrix.
4978+
// Reset the `_lyrics` array
4979+
this._lyrics = Array(this._lyrics.length).fill("");
4980+
const lyricsRow = document.getElementById("lyricRow");
4981+
if (lyricsRow) {
4982+
const inputFields = lyricsRow.querySelectorAll("input[type='text']");
4983+
inputFields.forEach((inputField, index) => {
4984+
inputField.value = this._lyrics[index] || "";
4985+
});
4986+
}
4987+
// 'Unclick' every entry in the matrix
48834988
let row, cell;
48844989
for (let i = 0; i < this.rowLabels.length; i++) {
48854990
row = this._rows[i];
@@ -4894,6 +4999,7 @@ class PhraseMaker {
48944999
}
48955000
}
48965001

5002+
48975003
/**
48985004
* Saves the current matrix state as an action stack consisting of note and pitch blocks.
48995005
* @private
@@ -5036,7 +5142,7 @@ class PhraseMaker {
50365142
if (obj === null) {
50375143
// add a hertz block
50385144
// The last connection in last pitch block is null.
5039-
if (note[0].length === 1 || j === note[0].length - 1) {
5145+
if (!this.lyricsON && (note[0].length === 1 || j === note[0].length - 1)) {
50405146
lastConnection = null;
50415147
} else {
50425148
lastConnection = thisBlock + 2;
@@ -5061,7 +5167,7 @@ class PhraseMaker {
50615167
} else if (drumName != null) {
50625168
// add a playdrum block
50635169
// The last connection in last pitch block is null.
5064-
if (note[0].length === 1 || j === note[0].length - 1) {
5170+
if (!this.lyricsON && (note[0].length === 1 || j === note[0].length - 1)) {
50655171
lastConnection = null;
50665172
} else {
50675173
lastConnection = thisBlock + 2;
@@ -5086,7 +5192,7 @@ class PhraseMaker {
50865192
} else if (note[0][j].slice(0, 4) === "http") {
50875193
// add a playdrum block with URL
50885194
// The last connection in last pitch block is null.
5089-
if (note[0].length === 1 || j === note[0].length - 1) {
5195+
if (!this.lyricsON && (note[0].length === 1 || j === note[0].length - 1)) {
50905196
lastConnection = null;
50915197
} else {
50925198
lastConnection = thisBlock + 2;
@@ -5111,7 +5217,7 @@ class PhraseMaker {
51115217
} else if (obj.length > 2) {
51125218
// add a 2-arg graphics block
51135219
// The last connection in last pitch block is null.
5114-
if (note[0].length === 1 || j === note[0].length - 1) {
5220+
if (!this.lyricsON && (note[0].length === 1 || j === note[0].length - 1)) {
51155221
lastConnection = null;
51165222
} else {
51175223
lastConnection = thisBlock + 3;
@@ -5143,7 +5249,7 @@ class PhraseMaker {
51435249
} else if (obj.length > 1) {
51445250
// add a 1-arg graphics block
51455251
// The last connection in last pitch block is null.
5146-
if (note[0].length === 1 || j === note[0].length - 1) {
5252+
if (!this.lyricsON && (note[0].length === 1 || j === note[0].length - 1)) {
51475253
lastConnection = null;
51485254
} else {
51495255
lastConnection = thisBlock + 2;
@@ -5168,7 +5274,7 @@ class PhraseMaker {
51685274
} else {
51695275
// add a pitch block
51705276
// The last connection in last pitch block is null.
5171-
if (note[0].length === 1 || j === note[0].length - 1) {
5277+
if (!this.lyricsON && (note[0].length === 1 || j === note[0].length - 1)) {
51725278
lastConnection = null;
51735279
} else {
51745280
lastConnection = thisBlock + 3;
@@ -5348,6 +5454,34 @@ class PhraseMaker {
53485454
}
53495455
}
53505456
}
5457+
if (this.lyricsON) {
5458+
newStack.push([
5459+
thisBlock,
5460+
"print",
5461+
0,
5462+
0,
5463+
[previousBlock, thisBlock + 1, null]
5464+
]);
5465+
previousBlock = thisBlock;
5466+
thisBlock += 1;
5467+
if (this._lyrics[i] && this._lyrics !== "") {
5468+
newStack.push([
5469+
thisBlock,
5470+
["text", { value: this._lyrics[i] }],
5471+
0,
5472+
0,
5473+
[previousBlock]
5474+
]);
5475+
} else {
5476+
newStack.push([
5477+
thisBlock,
5478+
["text", { value: "..." }],
5479+
0,
5480+
0,
5481+
[previousBlock]
5482+
]);
5483+
}
5484+
}
53515485
}
53525486
}
53535487

0 commit comments

Comments
 (0)