diff --git a/js/blocks/WidgetBlocks.js b/js/blocks/WidgetBlocks.js index 93353168ba..a1673ba059 100644 --- a/js/blocks/WidgetBlocks.js +++ b/js/blocks/WidgetBlocks.js @@ -23,7 +23,7 @@ function setupWidgetBlocks() { } flow(args, logo, turtle, blk) { - let tur = logo.turtles.ithTurtle(turtle); + const tur = logo.turtles.ithTurtle(turtle); if (args.length === 4 && typeof args[0] === "number") { if (args[0] < 0 || args[0] > 100) { @@ -101,7 +101,7 @@ function setupWidgetBlocks() { let rollOff; if (args.length === 3 && typeof args[1] === "number") { - for (let ftype in FILTERTYPES) { + for (const ftype in FILTERTYPES) { if (FILTERTYPES[ftype][0] === args[0]) { filtertype = FILTERTYPES[ftype][1]; } else if (FILTERTYPES[ftype][1] === args[0]) { @@ -185,31 +185,31 @@ function setupWidgetBlocks() { logo.insideTemperament = true; logo.temperament.inTemperament = args[0]; - let scale = []; + const scale = []; if ( logo.blocks.blockList[logo.blocks.blockList[blk].connections[2]] .name === "pitch" ) { - let pitchBlock = + const pitchBlock = logo.blocks.blockList[ logo.blocks.blockList[blk].connections[2] ]; - let note = + const note = logo.blocks.blockList[pitchBlock.connections[1]].value; - let octave = + const octave = logo.blocks.blockList[pitchBlock.connections[2]].value; - let setKey = logo.blocks.blockList[pitchBlock.connections[3]]; + const setKey = logo.blocks.blockList[pitchBlock.connections[3]]; scale[0] = logo.blocks.blockList[setKey.connections[1]].value; scale[1] = logo.blocks.blockList[setKey.connections[2]].value; logo.synth.startingPitch = note + octave; logo.temperament.scale = scale; } - let listenerName = "_temperament_" + turtle; + const listenerName = "_temperament_" + turtle; logo.setDispatchBlock(blk, turtle, listenerName); - let __listener = function(event) { + const __listener = function(event) { logo.temperament.init(); }; @@ -322,10 +322,10 @@ function setupWidgetBlocks() { logo.timbre.duoSynthParams = []; logo.timbre.notesToPlay = []; - let listenerName = "_timbre_" + turtle; + const listenerName = "_timbre_" + turtle; logo.setDispatchBlock(blk, turtle, listenerName); - let __listener = function(event) { + const __listener = function(event) { logo.timbre.init(); }; @@ -363,10 +363,10 @@ function setupWidgetBlocks() { flow(args, logo, turtle, blk) { logo.insideMeterWidget = true; - let listenerName = "_meterwidget_" + turtle; + const listenerName = "_meterwidget_" + turtle; logo.setDispatchBlock(blk, turtle, listenerName); - let __listener = function(event) { + const __listener = function(event) { logo.meterWidget = new MeterWidget(blk); logo.insideMeterWidget = false; @@ -391,18 +391,19 @@ function setupWidgetBlocks() { "oscilloscope" ]); this.formBlock({ name: _("oscilloscope"), canCollapse: true }); - let addPrintTurtle = (blocks,turtle,prev,last) => { - let len = blocks.length; - let next = last ? null : len+2 + const addPrintTurtle = (blocks,turtle,prev,last) => { + const len = blocks.length; + const next = last ? null : len+2; blocks.push([len, "print", 0, 0, [prev, len + 1, next]]); blocks.push([len + 1, ["text", { value: turtle.name}], 0, 0, [len, null]]); return blocks; - } + }; this.makeMacro((x, y) => { let blocks = [[0,"oscilloscope", x, y, [null, 1, null]]]; - for (let turtle of turtles.turtleList) { + for (const turtle of turtles.turtleList) { if (!turtle.inTrash) + // eslint-disable-next-line max-len blocks = addPrintTurtle(blocks, turtle, Math.max(0, blocks.length - 2), turtle == last(turtles.turtleList)); } blocks[0][4][2]=blocks.length; @@ -415,10 +416,10 @@ function setupWidgetBlocks() { logo.oscilloscopeTurtles = []; logo.inOscilloscope = true; - let listenerName = "_oscilloscope_" + turtle; + const listenerName = "_oscilloscope_" + turtle; logo.setDispatchBlock(blk, turtle, listenerName); - let __listener = function(event) { + const __listener = function(event) { logo.Oscilloscope = new Oscilloscope(logo); logo.inOscilloscope = false; }; @@ -457,10 +458,10 @@ function setupWidgetBlocks() { flow(args, logo, turtle, blk) { logo.insideModeWidget = true; - let listenerName = "_modewidget_" + turtle; + const listenerName = "_modewidget_" + turtle; logo.setDispatchBlock(blk, turtle, listenerName); - let __listener = function(event) { + const __listener = function(event) { logo.modeWidget = new ModeWidget(); logo.insideModeWidget = false; }; @@ -507,10 +508,10 @@ function setupWidgetBlocks() { logo.tempo.BPMBlocks = []; logo.tempo.BPMs = []; - let listenerName = "_tempo_" + turtle; + const listenerName = "_tempo_" + turtle; logo.setDispatchBlock(blk, turtle, listenerName); - let __listener = function(event) { + const __listener = function(event) { logo.tempo.init(); }; @@ -565,10 +566,10 @@ function setupWidgetBlocks() { logo.pitchDrumMatrix.drums = []; logo.pitchDrumMatrix.clearBlocks(); - let listenerName = "_pitchdrummatrix_" + turtle; + const listenerName = "_pitchdrummatrix_" + turtle; logo.setDispatchBlock(blk, turtle, listenerName); - let __listener = function(event) { + const __listener = function(event) { if ( logo.pitchDrumMatrix.drums.length === 0 || logo.pitchDrumMatrix.rowLabels.length === 0 @@ -622,10 +623,10 @@ function setupWidgetBlocks() { logo.inPitchSlider = true; logo.pitchSlider.frequencies = []; - let listenerName = "_pitchslider_" + turtle; + const listenerName = "_pitchslider_" + turtle; logo.setDispatchBlock(blk, turtle, listenerName); - let __listener = function(event) { + const __listener = function(event) { logo.pitchSlider.init(logo); logo.inPitchSlider = false; }; @@ -754,10 +755,10 @@ function setupWidgetBlocks() { logo.musicKeyboard.octaves = []; logo.musicKeyboard._rowBlocks = []; - let listenerName = "_musickeyboard_" + turtle; + const listenerName = "_musickeyboard_" + turtle; logo.setDispatchBlock(blk, turtle, listenerName); - let __listener = function(event) { + const __listener = function(event) { logo.musicKeyboard.init(logo); }; @@ -803,10 +804,10 @@ function setupWidgetBlocks() { logo.inPitchStaircase = true; - let listenerName = "_pitchstaircase_" + turtle; + const listenerName = "_pitchstaircase_" + turtle; logo.setDispatchBlock(blk, turtle, listenerName); - let __listener = function(event) { + const __listener = function(event) { logo.pitchStaircase.init(logo); logo.inPitchStaircase = false; }; @@ -890,11 +891,11 @@ function setupWidgetBlocks() { logo.rhythmRuler.Drums = []; logo.inRhythmRuler = true; - let listenerName = "_rhythmruler_" + turtle; + const listenerName = "_rhythmruler_" + turtle; logo.setDispatchBlock(blk, turtle, listenerName); - let __listener = function(event) { - logo.rhythmRuler = new RhythmRuler(); + const __listener = function(event) { + logo.rhythmRuler.init(); }; logo.setTurtleListener(turtle, listenerName, __listener); @@ -1033,10 +1034,10 @@ function setupWidgetBlocks() { logo.tupletParams = []; logo.addingNotesToTuplet = false; - let listenerName = "_matrix_" + turtle; + const listenerName = "_matrix_" + turtle; logo.setDispatchBlock(blk, turtle, listenerName); - let __listener = function(event) { + const __listener = function(event) { if ( logo.tupletRhythms.length === 0 || logo.phraseMaker.rowLabels.length === 0 @@ -1061,7 +1062,8 @@ function setupWidgetBlocks() { switch (logo.tupletRhythms[i][0]) { case "notes": case "simple": - let tupletParam = [logo.tupletParams[logo.tupletRhythms[i][1]]]; + // eslint-disable-next-line no-case-declarations + const tupletParam = [logo.tupletParams[logo.tupletRhythms[i][1]]]; tupletParam.push([]); for ( let j = 2; @@ -1138,10 +1140,10 @@ function setupWidgetBlocks() { logo.inStatusMatrix = true; - let listenerName = "_status_" + turtle; + const listenerName = "_status_" + turtle; logo.setDispatchBlock(blk, turtle, listenerName); - let __listener = function(event) { + const __listener = function(event) { logo.statusMatrix.init(logo); logo.inStatusMatrix = false; }; diff --git a/js/widgets/rhythmruler.js b/js/widgets/rhythmruler.js index 5078dbfd13..880b56cde4 100644 --- a/js/widgets/rhythmruler.js +++ b/js/widgets/rhythmruler.js @@ -1,18 +1,23 @@ -// Copyright (c) 2016-19 Walter Bender -// Copyright (c) 2016 Hemant Kasat -// This program is free software; you can redistribute it and/or -// modify it under the terms of the The GNU Affero General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// You should have received a copy of the GNU Affero General Public -// License along with this library; if not, write to the Free Software -// Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA +/** + * @file This contains the prototype of the rhythmruler Widget + * + * @copyright 2016-19 Walter Bender + * @copyright 2016 Hemant Kasat + * + * @license + * This program is free software; you can redistribute it and/or modify it under the terms of the + * The GNU Affero General Public License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * You should have received a copy of the GNU Affero General Public License along with this + * library; if not, write to the Free Software Foundation, 51 Franklin Street, Suite 500 Boston, + * MA 02110-1335 USA. + */ /* global TONEBPM, Singer, logo, _, delayExecution, docById, calcNoteValueToDisplay, platformColor, beginnerMode, last, EIGHTHNOTEWIDTH, nearestBeat, rationalToFraction, DRUMNAMES, VOICENAMES, - EFFECTSNAMES, wheelnav, slicePath + EFFECTSNAMES */ /* exported RhythmRuler */ @@ -27,24 +32,15 @@ * - `rulerTableDiv` is for the drum buttons (fixed first col) and the ruler cells */ class RhythmRuler { - static ROWHEIGHT = 130; static RULERHEIGHT = 70; static BUTTONSIZE = 51; static ICONSIZE = 32; static DEL = 46; + /** + * @constructor + */ constructor() { - // console.debug("init RhythmRuler"); - - this._bpmFactor = (1000 * TONEBPM) / Singer.masterBPM; - - this._playing = false; - this._playingOne = false; - this._playingAll = false; - this._rulerPlaying = -1; - this._startingTime = null; - this._expanded = false; - // There is one ruler per drum. this.Drums = []; // Rulers, one per drum, contain the subdivisions defined by rhythm blocks. @@ -84,6 +80,23 @@ class RhythmRuler { this._dissectNumber = null; this._progressBar = null; this._rulers = []; + } + + /** + * Initialises the temperament widget. + * @returns {void} + */ + init() { + // console.debug("init RhythmRuler"); + + this._bpmFactor = (1000 * TONEBPM) / Singer.masterBPM; + + this._playing = false; + this._playingOne = false; + this._playingAll = false; + this._rulerPlaying = -1; + this._startingTime = null; + this._expanded = false; // If there are no drums, add one. if (this.Drums.length === 0) { @@ -99,6 +112,7 @@ class RhythmRuler { } this._cellScale = 1.0; + const iconSize = RhythmRuler.ICONSIZE; const widgetWindow = window.widgetWindows.windowFor(this, "rhythm maker"); this.widgetWindow = widgetWindow; @@ -149,11 +163,7 @@ class RhythmRuler { this.widgetWindow.destroy(); }; - this._playAllCell = widgetWindow.addButton( - "play-button.svg", - RhythmRuler.ICONSIZE, - _("Play all") - ); + this._playAllCell = widgetWindow.addButton("play-button.svg", iconSize, _("Play all")); this._playAllCell.onclick = () => { if (this._playing) { this.__pause(); @@ -165,10 +175,10 @@ class RhythmRuler { this._save_lock = false; widgetWindow.addButton( "export-chunk.svg", - RhythmRuler.ICONSIZE, + iconSize, _("Save rhythms") ).onclick = async () => { - // that._save(0); + // this._save(0); // Debounce button if (!this._get_save_lock()) { this._save_lock = true; @@ -177,7 +187,7 @@ class RhythmRuler { this._saveTupletsMerged(this._mergeRulers()); // Rather than each ruler individually. - // that._saveTuplets(0); + // this._saveTuplets(0); await delayExecution(1000); this._save_lock = false; } @@ -185,7 +195,7 @@ class RhythmRuler { widgetWindow.addButton( "export-drums.svg", - RhythmRuler.ICONSIZE, + iconSize, _("Save drum machine") ).onclick = async () => { // Debounce button @@ -201,12 +211,11 @@ class RhythmRuler { this._dissectNumber = widgetWindow.addInputButton("2"); this._dissectNumber.onfocus = () => { - // that._piemenuNumber(['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16'], numberInput.value); + // this._piemenuNumber(['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16'], numberInput.value); }; this._dissectNumber.onkeydown = (event) => { - // 46 number is for the delete keypress - if (event.keyCode === 46) { + if (event.keyCode === RhythmRuler.DEL) { this._dissectNumber.value = this._dissectNumber.value.substring( 0, this._dissectNumber.value.length - 1 @@ -223,30 +232,18 @@ class RhythmRuler { this._dissectNumber.value = Math.max(Math.min(this._dissectNumber.value, 128), 2); }; - widgetWindow.addButton( - "restore-button.svg", - RhythmRuler.ICONSIZE, - _("Undo") - ).onclick = () => { + widgetWindow.addButton("restore-button.svg", iconSize, _("Undo")).onclick = () => { this._undo(); }; //.TRANS: user can tap out a rhythm by clicking on a ruler. - this._tapButton = widgetWindow.addButton( - "tap-button.svg", - RhythmRuler.ICONSIZE, - _("Tap a rhythm") - ); + this._tapButton = widgetWindow.addButton("tap-button.svg", iconSize, _("Tap a rhythm")); this._tapButton.onclick = () => { this._tap(); }; //.TRANS: clear all subdivisions from the ruler. - widgetWindow.addButton( - "erase-button.svg", - RhythmRuler.ICONSIZE, - _("Clear") - ).onclick = () => { + widgetWindow.addButton("erase-button.svg", iconSize, _("Clear")).onclick = () => { this._clear(); }; @@ -279,9 +276,9 @@ class RhythmRuler { '" alt="' + _("Play") + '" height="' + - RhythmRuler.ICONSIZE + + iconSize + '" width="' + - RhythmRuler.ICONSIZE + + iconSize + '" />'; drumcell.className = "headcol"; // Position fixed when scrolling horizontally @@ -295,9 +292,9 @@ class RhythmRuler { '" alt="' + _("Play") + '" height="' + - RhythmRuler.ICONSIZE + + iconSize + '" width="' + - RhythmRuler.ICONSIZE + + iconSize + '" vertical-align="middle">'; this._playing = false; this._playingOne = false; @@ -324,9 +321,9 @@ class RhythmRuler { '" alt="' + _("Pause") + '" height="' + - RhythmRuler.ICONSIZE + + iconSize + '" width="' + - RhythmRuler.ICONSIZE + + iconSize + '" vertical-align="middle">'; this._elapsedTimes[id] = 0; this._offsets[id] = 0; @@ -425,12 +422,11 @@ class RhythmRuler { this._dissectHistory[i][0][j][1], false ); + } else { + // console.warn( + // "Could not find cell to divide. Did the order of the rhythm blocks change?" + // ); } - // else { - // console.warn( - // "Could not find cell to divide. Did the order of the rhythm blocks change?" - // ); - // } } else { // divide is [cell, [values]] cell = rhythmRulerTableRow.cells[this._dissectHistory[i][0][j][0]]; @@ -462,10 +458,20 @@ class RhythmRuler { // this._piemenuRuler(this._rulerSelected); } + /** + * @private + * @param {number} noteValue + * @returns {void} + */ _noteWidth(noteValue) { return Math.floor(EIGHTHNOTEWIDTH * (8 / Math.abs(noteValue)) * 4); } + /** + * @private + * @param {number} rulerno + * @returns {void} + */ _calculateZebraStripes(rulerno) { const ruler = this._rulers[rulerno]; let evenColor; @@ -497,6 +503,12 @@ class RhythmRuler { } } + /** + * @private + * @param {string} ruler + * @param {Event} event - The triggering event. + * @returns {void} + */ _dissectRuler(event, ruler) { const cell = event.target; if (cell === null) { @@ -568,7 +580,7 @@ class RhythmRuler { } setTimeout(() => { - this.__startTapping(noteValues, interval, event); + this.__startTapping(interval, event); }, interval); } } else { @@ -591,7 +603,14 @@ class RhythmRuler { this.saveDissectHistory(); } - __startTapping(noteValues, interval, event) { + /** + * @private + * @param {number} noteValues + * @param {Event} event - The triggering event. + * @param {number} interval + * @returns {void} + */ + __startTapping(interval, event) { const d = new Date(); this._tapTimes = [d.getTime()]; this._tapEndTime = this._tapTimes[0] + interval; @@ -621,6 +640,11 @@ class RhythmRuler { __move(interval / 8, 100 / 8); } + /** + * @private + * @param {Event} event - The triggering event. + * @returns {void} + */ __endTapping(event) { const cell = event.target; if (cell.parentNode === null) { @@ -683,6 +707,8 @@ class RhythmRuler { const newNoteValues = []; let sum = 0; let obj; + // let interval = + // this._bpmFactor / Math.abs(noteValues[this._tapCell.cellIndex]); for (let i = 1; i < this._tapTimes.length; i++) { const dtime = this._tapTimes[i] - this._tapTimes[i - 1]; if (i < this._tapTimes.length - 1) { @@ -711,6 +737,7 @@ class RhythmRuler { this._tapTimes = []; this._tapCell = null; this._tapEndTime = null; + // let iconSize = RhythmRuler.ICONSIZE; this._tapButton.innerHTML = ''; } + /** + * @private + * @param {HTMLElement} cell - The HTML element target + * @param {number} cellWidth + * @param {number} noteValue + * @returns {void} + */ __addCellEventHandlers(cell, cellWidth, noteValue) { const __mouseOverHandler = (event) => { const cell = event.target; @@ -762,11 +796,12 @@ class RhythmRuler { // occasionally confuses tone.js during rapid clicking // in the widget. - // that._logo.synth.trigger(0, 'C4', 1 / 32, 'chime', null, null); + // logo.synth.trigger(0, 'C4', 1 / 32, 'chime', null, null); const cell = this._mouseDownCell; if (cell !== null && cell.parentNode !== null) { this._rulerSelected = cell.parentNode.getAttribute("data-row"); + // const noteValues = this.Rulers[this._rulerSelected][0]; cell.style.backgroundColor = platformColor.selectorBackground; } }, 1500); @@ -798,10 +833,9 @@ class RhythmRuler { const cell = event.target; if (cell !== null && cell.parentNode !== null) { this._dissectRuler(event, cell.parentNode.getAttribute("data-row")); + } else { + // console.error("Rhythm Ruler: null cell found on click"); } - // else { - // console.error("Rhythm Ruler: null cell found on click"); - // } } this._inLongPress = false; @@ -831,10 +865,20 @@ class RhythmRuler { cell.addEventListener("click", __clickHandler); } + /** + * @private + * @returns {void} + */ __getLongPressStatus() { return this._inLongPress; } + /** + * @private + * @param {number} cellWidth + * @param {boolean} addToUndoList + * @returns {void} + */ __toggleRestState(cell, addToUndoList) { if (cell !== null && cell.parentNode !== null) { this._rulerSelected = cell.parentNode.getAttribute("data-row"); @@ -900,6 +944,13 @@ class RhythmRuler { // this._piemenuRuler(this._rulerSelected); } + /** + * @private + * @param {HTMLElement} cell - The HTML element target + * @param {number} newNoteValues + * @param {boolean} addToUndoList + * @returns {void} + */ __divideFromList(cell, newNoteValues, addToUndoList) { if (typeof cell !== "object") { return; @@ -923,6 +974,8 @@ class RhythmRuler { divisionHistory.push([newCellIndex, newNoteValues]); ruler.deleteCell(newCellIndex); + + // let noteValue = noteValues[newCellIndex]; // let tempwidth = this._noteWidth(newNoteValue); noteValues.splice(newCellIndex, 1); @@ -947,6 +1000,13 @@ class RhythmRuler { // this._piemenuRuler(this._rulerSelected); } + /** + * @private + * @param {HTMLElement} cell - The HTML element target + * @param {number} inputNum + * @param {boolean} addToUndoList + * @returns {void} + */ __dissectByNumber(cell, inputNum, addToUndoList) { if (typeof cell !== "object") { return; @@ -1010,6 +1070,12 @@ class RhythmRuler { // this._piemenuRuler(this._rulerSelected); } + /** + * @private + * @param {Event} event - The triggering event. + * @param {string} ruler + * @returns {void} + */ _tieRuler(event, ruler) { if (this._playing) { // console.warn("You cannot tie while widget is playing."); @@ -1030,6 +1096,11 @@ class RhythmRuler { // this._piemenuRuler(this._rulerSelected); } + /** + * @private + * @param {boolean} addToUndoList + * @returns {void} + */ __tie(addToUndoList) { const ruler = this._rulers[this._rulerSelected]; @@ -1109,6 +1180,10 @@ class RhythmRuler { } } + /** + * @private + * @returns {void} + */ _undo() { // FIXME: Add undo for REST logo.synth.stop(); @@ -1167,7 +1242,8 @@ class RhythmRuler { const newCellIndex = last(divisionHistory)[0]; const oldNoteValues = last(divisionHistory)[1]; - // Calculate the new note value based on the sum of the oldnoteValues. + // Calculate the new note value based on the sum of the + // oldnoteValues. let sum = 0; for (let i = 0; i < oldNoteValues.length; i++) { sum += 1 / oldNoteValues[i]; @@ -1229,10 +1305,9 @@ class RhythmRuler { } this.Rulers[lastRuler][0] = noteValues; + } else { + // console.warn("empty history encountered... skipping undo"); } - // else { - // console.warn("empty history encountered... skipping undo"); - // } } else if (obj[0] === "rest") { const newCellIndex = last(divisionHistory); const cell = ruler.cells[newCellIndex]; @@ -1246,20 +1321,29 @@ class RhythmRuler { // this._piemenuRuler(this._rulerSelected); } + /** + * @private + * @returns {void} + */ _tap() { this._tapMode = true; + const iconSize = RhythmRuler.ICONSIZE; this._tapButton.innerHTML = '' +
             _('; } + /** + * @private + * @returns {void} + */ _clear() { logo.synth.stop(); logo.resetSynth(0); @@ -1288,6 +1372,10 @@ class RhythmRuler { // this._piemenuRuler(this._rulerSelected); } + /** + * @private + * @returns {void} + */ __pause() { this._playAllCell.innerHTML = ' { return a - b; }); @@ -2569,12 +2287,21 @@ class RhythmRuler { return noteValues; } + /** + * @private + * @returns {boolean} + */ _get_save_lock() { return this._save_lock; } + /** + * @public + * @returns {void} + */ saveDissectHistory() { // Save the new dissect history. + const dissectHistory = []; const drums = []; let drum; @@ -2606,10 +2333,7 @@ class RhythmRuler { this._dissectHistory = JSON.parse(JSON.stringify(dissectHistory)); } - /** - * @deprecated - */ - _piemenuRuler(/* selectedRuler */) { + _piemenuRuler() { return; // In progress /* // piemenu version of ruler @@ -2658,89 +2382,10 @@ class RhythmRuler { */ } - _piemenuNumber(wheelValues, selectedValue) { - // input form and wheelNav pie menu for number selection - docById("wheelDiv").style.display = ""; - - // the number selector - this._numberWheel = new wheelnav("wheelDiv", null, 600, 600); - // exit button - this._exitWheel = new wheelnav("_exitWheel", this._numberWheel.raphael); - - const wheelLabels = []; - for (let i = 0; i < wheelValues.length; i++) { - wheelLabels.push(wheelValues[i].toString()); - } - - // spacer - wheelLabels.push(null); - - wheelnav.cssMode = true; - - this._numberWheel.keynavigateEnabled = true; - - this._numberWheel.colors = ["#ffb2bc", "#ffccd6"]; - this._numberWheel.slicePathFunction = slicePath().DonutSlice; - this._numberWheel.slicePathCustom = slicePath().DonutSliceCustomization(); - this._numberWheel.slicePathCustom.minRadiusPercent = 0.2; - if (wheelValues.length > 16) { - this._numberWheel.slicePathCustom.maxRadiusPercent = 1.0; - } else { - this._numberWheel.slicePathCustom.maxRadiusPercent = 0.6; - } - - this._numberWheel.sliceSelectedPathCustom = this._numberWheel.slicePathCustom; - this._numberWheel.sliceInitPathCustom = this._numberWheel.slicePathCustom; - // this._numberWheel.titleRotateAngle = 0; - this._numberWheel.animatetime = 300; - this._numberWheel.createWheel(wheelLabels); - - this._exitWheel.colors = ["#808080", "#c0c0c0"]; - this._exitWheel.slicePathFunction = slicePath().DonutSlice; - this._exitWheel.slicePathCustom = slicePath().DonutSliceCustomization(); - this._exitWheel.slicePathCustom.minRadiusPercent = 0.0; - this._exitWheel.slicePathCustom.maxRadiusPercent = 0.2; - this._exitWheel.sliceSelectedPathCustom = this._exitWheel.slicePathCustom; - this._exitWheel.sliceInitPathCustom = this._exitWheel.slicePathCustom; - this._exitWheel.clickModeRotate = false; - this._exitWheel.createWheel(["x", " "]); - - const __selectionChanged = () => { - this._dissectNumber.value = wheelValues[this._numberWheel.selectedNavItemIndex]; - }; - - const __exitMenu = () => { - const d = new Date(); - this._piemenuExitTime = d.getTime(); - docById("wheelDiv").style.display = "none"; - this._numberWheel.removeWheel(); - this._exitWheel.removeWheel(); - }; - - this._positionWheel(); - - // Navigate to a the current number value. - let i = wheelValues.indexOf(selectedValue); - if (i === -1) { - i = 0; - } - - this._numberWheel.navigateWheel(i); - - // Hide the widget when the selection is made. - for (let i = 0; i < wheelLabels.length; i++) { - this._numberWheel.navItems[i].navigateFunction = function () { - __selectionChanged(); - __exitMenu(); - }; - } - - // Or use the exit wheel... - this._exitWheel.navItems[0].navigateFunction = function () { - __exitMenu(); - }; - } - + /** + * @private + * @returns {void} + */ _positionWheel() { if (docById("wheelDiv").style.display == "none") { return;