vibe-editor 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +65 -61
- package/src/scripts/js/Core.js +28 -9
- package/src/scripts/js/entry.js +6 -5
- package/src/scripts/js/gui/Annotations.js +27 -12
- package/src/scripts/js/gui/ScoreManipulator.js +6 -4
- package/src/scripts/js/gui/Tabbar.js +13 -4
- package/src/scripts/js/handlers/AnnotationChangeHandler.js +13 -1
- package/src/scripts/js/handlers/InsertModeHandler.js +3 -3
- package/src/scripts/js/handlers/PhantomElementHandler.js +3 -10
- package/src/scripts/js/handlers/WindowHandler.js +7 -7
- package/src/scripts/js/scripts/Core.js +932 -0
- package/src/scripts/js/scripts/MusicProcessor.js +810 -0
- package/src/scripts/js/scripts/VIBE.js +219 -0
- package/src/scripts/js/scripts/datastructures/MeasureMatrix.js +156 -0
- package/src/scripts/js/scripts/gui/Annotations.js +549 -0
- package/src/scripts/js/scripts/gui/Cursor.js +203 -0
- package/src/scripts/js/scripts/gui/PhantomElement.js +132 -0
- package/src/scripts/js/scripts/gui/ScoreManipulator.js +188 -0
- package/src/scripts/js/scripts/gui/Tabbar.js +705 -0
- package/src/scripts/js/{gui/Toolbar copy.js → scripts/gui/Toolbar.js} +15 -11
- package/src/scripts/js/scripts/handlers/AnnotationChangeHandler.js +650 -0
- package/src/scripts/js/scripts/handlers/ClickModeHandler.js +535 -0
- package/src/scripts/js/{gui → scripts/handlers}/CustomAnnotationShapeDrawer.js +34 -17
- package/src/scripts/js/{handlers/ModHandler.js → scripts/handlers/CustomToolbarHandler.js} +54 -66
- package/src/scripts/js/scripts/handlers/GlobalKeyboardHandler.js +372 -0
- package/src/scripts/js/scripts/handlers/Handler.js +2 -0
- package/src/scripts/js/{handlers/InsertModeHandler_deprecated.js → scripts/handlers/InsertModeHandler.js} +117 -164
- package/src/scripts/js/scripts/handlers/KeyModeHandler.js +405 -0
- package/src/scripts/js/scripts/handlers/LabelHandler.js +463 -0
- package/src/scripts/js/scripts/handlers/NoteDragHandler.js +97 -0
- package/src/scripts/js/scripts/handlers/PhantomElementHandler.js +168 -0
- package/src/scripts/js/scripts/handlers/ScoreManipulatorHandler.js +233 -0
- package/src/scripts/js/scripts/handlers/SidebarHandler.js +506 -0
- package/src/scripts/js/scripts/handlers/TooltipHandler.js +132 -0
- package/src/scripts/js/scripts/handlers/WindowHandler.js +278 -0
- package/src/scripts/js/scripts/utils/MEIOperations.js +2121 -0
- package/src/scripts/js/{utils/Mouse2MEI.js → scripts/utils/Mouse2SVG.js} +225 -57
- package/src/scripts/js/scripts/utils/SVGEditor.js +453 -0
- package/src/scripts/js/scripts/utils/Types.js +2 -0
- package/src/scripts/js/{utils/VerovioWrapper copy.js → scripts/utils/VerovioWrapper.js} +35 -21
- package/src/scripts/js/scripts/utils/coordinates.js +54 -0
- package/src/scripts/js/utils/Mouse2SVG.js +11 -4
- package/src/scripts/js/utils/VerovioWrapper.js +4 -4
- package/src/scripts/js/utils/coordinates.js +26 -2
- package/src/scripts/js/.DS_Store +0 -0
- package/src/scripts/js/MusicPlayer.js +0 -572
- package/src/scripts/js/datastructures/ScoreGraph copy.js +0 -432
- package/src/scripts/js/gui/CustomAnnotationDrawer.js +0 -114
- package/src/scripts/js/handlers/AnnotationDragHandler.js +0 -113
- package/src/scripts/js/handlers/AnnotationLineHandler.js +0 -113
- package/src/scripts/js/handlers/ArticulationHandler.js +0 -20
- package/src/scripts/js/handlers/HarmonyHandler.js +0 -282
- package/src/scripts/js/handlers/InsertModeHandler copy.js +0 -423
- package/src/scripts/js/handlers/KeyModeHandler copy.js +0 -407
- package/src/scripts/js/handlers/KeyModeHandler_deprecated.js +0 -411
- package/src/scripts/js/handlers/NoteDragHandler copy.js +0 -148
- package/src/scripts/js/handlers/NoteDragHandler_deprecated.js +0 -150
- package/src/scripts/js/handlers/SelectionHandler.js +0 -262
- package/src/scripts/js/utils/RectWrapper.js +0 -10
- package/src/scripts/js/utils/SVGFiller.js +0 -245
- package/src/scripts/js/utils/VerovioWrapperLocal.js +0 -156
- package/src/scripts/js/utils/firefoxBBoxes.js +0 -143
- package/src/styles/vibe.css +0 -785
- /package/src/scripts/js/{assets → scripts/assets}/mei_template.js +0 -0
- /package/src/scripts/js/{constants.js → scripts/constants.js} +0 -0
- /package/src/scripts/js/{datastructures → scripts/datastructures}/ScoreGraph.js +0 -0
- /package/src/scripts/js/{datastructures → scripts/datastructures}/ScoreGraph_deprecated.js +0 -0
- /package/src/scripts/js/{datastructures → scripts/datastructures}/ScoreNode.js +0 -0
- /package/src/scripts/js/{gui → scripts/gui}/HarmonyLabel.js +0 -0
- /package/src/scripts/js/{gui → scripts/gui}/Label.js +0 -0
- /package/src/scripts/js/{gui → scripts/gui}/TempoLabel.js +0 -0
- /package/src/scripts/js/{handlers → scripts/handlers}/DeleteHandler.js +0 -0
- /package/src/scripts/js/{utils → scripts/utils}/DOMCreator.js +0 -0
- /package/src/scripts/js/{utils → scripts/utils}/MEIConverter.js +0 -0
- /package/src/scripts/js/{utils → scripts/utils}/ReactWrapper.js +0 -0
- /package/src/scripts/js/{utils → scripts/utils}/convenienceQueries.js +0 -0
- /package/src/scripts/js/{utils → scripts/utils}/mappings.js +0 -0
- /package/src/scripts/js/{utils → scripts/utils}/random.js +0 -0
@@ -0,0 +1,463 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const meiConverter = require("../utils/MEIConverter");
|
4
|
+
const meiOperation = require("../utils/MEIOperations");
|
5
|
+
const constants_1 = require("../constants");
|
6
|
+
const random_1 = require("../utils/random");
|
7
|
+
const HarmonyLabel_1 = require("../gui/HarmonyLabel");
|
8
|
+
const TempoLabel_1 = require("../gui/TempoLabel");
|
9
|
+
const cq = require("../utils/convenienceQueries");
|
10
|
+
const mappings_1 = require("../utils/mappings");
|
11
|
+
const labelClasses = ["harm", "tempo", "note", "chord", "fb"];
|
12
|
+
const labelSelectors = "." + labelClasses.join(",.");
|
13
|
+
class LabelHandler {
|
14
|
+
constructor(containerId) {
|
15
|
+
this.setHarmonyLabelHandlerClick = (function setHarmonyLabelHandler(e) {
|
16
|
+
//if (this.container.classList.contains("harmonyMode")) {
|
17
|
+
if (this.container.querySelector("#annotGroupKM > #harmonyAnnotButton.selected")) {
|
18
|
+
this.harmonyLabelHandler(e);
|
19
|
+
}
|
20
|
+
}).bind(this);
|
21
|
+
this.setTempoLabelHandlerClick = (function setTempoLabelHandlerClick(e) {
|
22
|
+
this.tempoLabelHandler(e);
|
23
|
+
}).bind(this);
|
24
|
+
this.setHarmonyLabelHandlerKey = (function setHarmonyLabelHandler(e) {
|
25
|
+
if (!cq.hasActiveElement(this.containerId))
|
26
|
+
return;
|
27
|
+
var isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
|
28
|
+
var ctrl = e.ctrlKey;
|
29
|
+
if (isMac) {
|
30
|
+
ctrl = e.metaKey;
|
31
|
+
}
|
32
|
+
if (ctrl) {
|
33
|
+
if (e.key === "k" && Array.from(this.vrvSVG.querySelectorAll(".note, .chord, .rest, .mrest")).some(el => el.classList.contains("marked"))) {
|
34
|
+
e.preventDefault();
|
35
|
+
this.harmonyLabelHandler(e);
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}).bind(this);
|
39
|
+
this.activateHarmonyHighlight = (function highlightNextHarmonyHandler(e) {
|
40
|
+
if (e.type === "mouseleave" && !this.isGlobal) {
|
41
|
+
this.interactionOverlay.addEventListener("mousemove", this.activateHarmonyHighlight);
|
42
|
+
}
|
43
|
+
if (!this.isGlobal) {
|
44
|
+
this.highlightNextHarmony(e);
|
45
|
+
}
|
46
|
+
}).bind(this);
|
47
|
+
this.deactivateHarmonyHighlight = (function deactivateHighlight(e) {
|
48
|
+
// document.querySelectorAll(".marked").forEach(m => {
|
49
|
+
// m.classList.remove("marked")
|
50
|
+
// })
|
51
|
+
this.interactionOverlay.removeEventListener("mousemove", this.activateHarmonyHighlight);
|
52
|
+
}).bind(this);
|
53
|
+
this.modifyLabelHandler = (function modifyLabelHandler(e) {
|
54
|
+
e.stopImmediatePropagation();
|
55
|
+
this.vrvSVG.querySelectorAll(".marked").forEach(m => {
|
56
|
+
var _a;
|
57
|
+
m.classList.remove("marked");
|
58
|
+
(_a = this.interactionOverlay.querySelector("*[refId=" + m.id + "]")) === null || _a === void 0 ? void 0 : _a.classList.remove("marked");
|
59
|
+
});
|
60
|
+
this.modifyLabel(e);
|
61
|
+
}).bind(this);
|
62
|
+
/**
|
63
|
+
* Wrapper function for submitlabel()
|
64
|
+
*/
|
65
|
+
this.submitLabelHandler = (function submitHandler(e) {
|
66
|
+
if (!cq.hasActiveElement(this.containerId))
|
67
|
+
return;
|
68
|
+
if (e.key === "Enter" && this.labelCanvas.hasChildNodes()) {
|
69
|
+
e.target.removeEventListener("keydown", this.submitLabelHandler);
|
70
|
+
this.submitLabel();
|
71
|
+
}
|
72
|
+
}).bind(this);
|
73
|
+
this.typeLabelHandler = (function (e) {
|
74
|
+
if (!cq.hasActiveElement(this.containerId))
|
75
|
+
return;
|
76
|
+
var factor = 1.3;
|
77
|
+
var t = e.target;
|
78
|
+
var parent = t.parentElement;
|
79
|
+
var tWidth = (t.getBoundingClientRect().width * factor).toString();
|
80
|
+
var tHeigth = (t.getBoundingClientRect().height * factor).toString();
|
81
|
+
parent.setAttribute("width", tWidth);
|
82
|
+
parent.setAttribute("height", tHeigth);
|
83
|
+
}).bind(this);
|
84
|
+
this.closeModifyWindowHandler = (function closeModifyWindow(e) {
|
85
|
+
if (e instanceof KeyboardEvent) {
|
86
|
+
if (e.key === "Escape") {
|
87
|
+
this.closeModifyWindow();
|
88
|
+
}
|
89
|
+
}
|
90
|
+
else if (e instanceof MouseEvent && !e.target.classList.contains("labelFO")) {
|
91
|
+
this.closeModifyWindow();
|
92
|
+
}
|
93
|
+
}).bind(this);
|
94
|
+
this.setContainerId(containerId);
|
95
|
+
this.addCanvas();
|
96
|
+
}
|
97
|
+
/**
|
98
|
+
* Set own canvas for manipulating labels
|
99
|
+
*/
|
100
|
+
addCanvas() {
|
101
|
+
this.rootBBox = this.interactionOverlay.getBoundingClientRect();
|
102
|
+
var rootWidth = this.rootBBox.width.toString();
|
103
|
+
var rootHeigth = this.rootBBox.height.toString();
|
104
|
+
var vb = this.interactionOverlay.getAttribute("viewBox");
|
105
|
+
this.labelCanvas = this.interactionOverlay.querySelector("#labelCanvas");
|
106
|
+
if (!this.labelCanvas) {
|
107
|
+
this.labelCanvas = document.createElementNS(constants_1.constants._SVGNS_, "svg");
|
108
|
+
this.labelCanvas.setAttribute("id", "labelCanvas");
|
109
|
+
this.labelCanvas.classList.add("canvas");
|
110
|
+
//this.labelCanvas.setAttribute("viewBox", ["0", "0", rootWidth, rootHeigth].join(" "))
|
111
|
+
}
|
112
|
+
//this.labelCanvas.setAttribute("viewBox", vb)
|
113
|
+
this.interactionOverlay.insertBefore(this.labelCanvas, this.interactionOverlay.firstChild);
|
114
|
+
return this;
|
115
|
+
}
|
116
|
+
/**
|
117
|
+
* Create label instances for elements already present in the score.
|
118
|
+
*/
|
119
|
+
initLabels() {
|
120
|
+
this.labels = new Map();
|
121
|
+
this.vrvSVG.querySelectorAll(labelSelectors).forEach(el => {
|
122
|
+
var _a;
|
123
|
+
var className = labelClasses.filter(l => this.vrvSVG.querySelector("#" + el.id).classList.contains(l))[0];
|
124
|
+
var inputString = "";
|
125
|
+
switch (className) {
|
126
|
+
case "harm":
|
127
|
+
if (el.querySelector(".fb") !== null) {
|
128
|
+
this.currentMEI.querySelectorAll("#" + el.id + " f").forEach(f => {
|
129
|
+
inputString += " " + f.textContent;
|
130
|
+
});
|
131
|
+
inputString = inputString.trim();
|
132
|
+
}
|
133
|
+
else {
|
134
|
+
inputString = this.currentMEI.getElementById(el.id).textContent;
|
135
|
+
}
|
136
|
+
this.labels.set(el.id, new HarmonyLabel_1.default(inputString, el.id, this.currentMEI));
|
137
|
+
break;
|
138
|
+
case "tempo":
|
139
|
+
inputString = ((_a = Array.from(this.vrvSVG.querySelector("#" + el.id).querySelectorAll(".text")).filter(e => /\d+/.test(e.textContent))[0]) === null || _a === void 0 ? void 0 : _a.textContent.match(/\d+/).join("")) || "";
|
140
|
+
this.labels.set(el.id, new TempoLabel_1.default(inputString, el.id, this.currentMEI));
|
141
|
+
break;
|
142
|
+
}
|
143
|
+
});
|
144
|
+
}
|
145
|
+
setListeners() {
|
146
|
+
document.querySelectorAll(".sylTextRect").forEach(s => {
|
147
|
+
s.remove();
|
148
|
+
});
|
149
|
+
// isGlobal = false: Editor is not in harmony mode
|
150
|
+
if (!this.isGlobal) {
|
151
|
+
this.interactionOverlay.addEventListener("click", this.setHarmonyLabelHandlerClick, true);
|
152
|
+
this.interactionOverlay.addEventListener("mousemove", this.activateHarmonyHighlight);
|
153
|
+
this.interactionOverlay.addEventListener("keydown", this.closeModifyWindowHandler, true);
|
154
|
+
}
|
155
|
+
this.interactionOverlay.addEventListener("click", this.closeModifyWindowHandler);
|
156
|
+
document.addEventListener("keydown", this.setHarmonyLabelHandlerKey);
|
157
|
+
this.interactionOverlay.querySelectorAll(labelSelectors).forEach(h => {
|
158
|
+
h.addEventListener("mouseover", this.deactivateHarmonyHighlight);
|
159
|
+
h.addEventListener("mouseleave", this.activateHarmonyHighlight);
|
160
|
+
h.addEventListener("dblclick", this.modifyLabelHandler);
|
161
|
+
});
|
162
|
+
this.interactionOverlay.querySelectorAll(".harm, .label, .manipulator").forEach(h => h.addEventListener("click", (e) => {
|
163
|
+
e.stopImmediatePropagation();
|
164
|
+
e.stopPropagation();
|
165
|
+
})); // prevent inseerting notes, wenn cursor is over a harm symbol
|
166
|
+
return this;
|
167
|
+
}
|
168
|
+
removeListeners() {
|
169
|
+
this.interactionOverlay.removeEventListener("click", this.closeModifyWindowHandler);
|
170
|
+
this.interactionOverlay.removeEventListener("click", this.setHarmonyLabelHandlerClick);
|
171
|
+
document.removeEventListener("keydown", this.setHarmonyLabelHandlerKey);
|
172
|
+
this.interactionOverlay.removeEventListener("mousemove", this.activateHarmonyHighlight);
|
173
|
+
this.interactionOverlay.removeEventListener("keydown", this.closeModifyWindowHandler);
|
174
|
+
this.interactionOverlay.querySelectorAll(labelSelectors).forEach(h => {
|
175
|
+
h.removeEventListener("mouseenter", this.deactivateHarmonyHighlight);
|
176
|
+
h.removeEventListener("mouseleave", this.activateHarmonyHighlight);
|
177
|
+
h.removeEventListener("dblclick", this.modifyLabelHandler);
|
178
|
+
});
|
179
|
+
return this;
|
180
|
+
}
|
181
|
+
// HARMONY LABELS
|
182
|
+
/**
|
183
|
+
* Open Inputbox for (first) selected Note
|
184
|
+
*/
|
185
|
+
harmonyLabelHandler(e) {
|
186
|
+
var nextNote = this.vrvSVG.querySelector(".note.marked, .chord.marked");
|
187
|
+
if (nextNote === null) {
|
188
|
+
return;
|
189
|
+
}
|
190
|
+
var nextNoteBBox = nextNote.getBoundingClientRect();
|
191
|
+
var staffBBox = nextNote.closest(".staff").getBoundingClientRect();
|
192
|
+
var canvasMatrix = this.labelCanvas.getScreenCTM().inverse();
|
193
|
+
var ptNoteLT = new DOMPoint(nextNoteBBox.left, nextNoteBBox.top);
|
194
|
+
ptNoteLT = ptNoteLT.matrixTransform(canvasMatrix);
|
195
|
+
var ptNoteRB = new DOMPoint(nextNoteBBox.right, nextNoteBBox.bottom);
|
196
|
+
ptNoteRB = ptNoteRB.matrixTransform(canvasMatrix);
|
197
|
+
var ptNoteWidth = Math.abs(ptNoteRB.x - ptNoteLT.x);
|
198
|
+
var ptNoteHeight = Math.abs(ptNoteRB.y - ptNoteLT.y);
|
199
|
+
var ptStaffLT = new DOMPoint(staffBBox.left, staffBBox.top);
|
200
|
+
ptStaffLT = ptStaffLT.matrixTransform(canvasMatrix);
|
201
|
+
var ptStaffRB = new DOMPoint(staffBBox.right, staffBBox.bottom);
|
202
|
+
ptStaffRB = ptStaffRB.matrixTransform(canvasMatrix);
|
203
|
+
var ptStaffWidth = Math.abs(ptStaffRB.x - ptStaffLT.x);
|
204
|
+
var ptStaffHeight = Math.abs(ptStaffRB.y - ptStaffLT.y);
|
205
|
+
var posx = ptNoteLT.x - ptNoteWidth / 2; //nextNoteBBox.left - nextNoteBBox.width/2 - window.scrollX - rootBBox.x - root.scrollLeft
|
206
|
+
var posy = ptStaffRB.y; //staffBBox.bottom - window.scrollY - rootBBox.y - root.scrollLeft
|
207
|
+
var tstamp = meiOperation.getElementTimestampById(nextNote.id, this.currentMEI);
|
208
|
+
var existsTstamp = Array.from(this.currentMEI.getElementById(nextNote.id).closest("measure").querySelectorAll("harm")).some(h => {
|
209
|
+
if (h.getAttribute("tstamp") !== null) {
|
210
|
+
return parseFloat(h.getAttribute("tstamp")) === tstamp;
|
211
|
+
}
|
212
|
+
else {
|
213
|
+
return false;
|
214
|
+
}
|
215
|
+
});
|
216
|
+
var hasStartId = this.currentMEI.querySelector("harm[startid=\"" + nextNote.id + "\"]") !== null;
|
217
|
+
var isEmptyLabelCanvas = !this.labelCanvas.hasChildNodes();
|
218
|
+
if (!hasStartId && isEmptyLabelCanvas && !existsTstamp) {
|
219
|
+
this.createInputBox(posx, posy, nextNote.id, "harm");
|
220
|
+
}
|
221
|
+
else if (!isEmptyLabelCanvas) {
|
222
|
+
this.closeModifyWindow();
|
223
|
+
}
|
224
|
+
}
|
225
|
+
setLabel(labelString, bboxId) {
|
226
|
+
var className = labelClasses.filter(l => this.vrvSVG.querySelector("#" + bboxId).classList.contains(l))[0];
|
227
|
+
var label;
|
228
|
+
switch (className) {
|
229
|
+
case "note":
|
230
|
+
case "chord":
|
231
|
+
case "harm":
|
232
|
+
label = new HarmonyLabel_1.default(labelString, bboxId, this.currentMEI);
|
233
|
+
break;
|
234
|
+
case "tempo":
|
235
|
+
label = new TempoLabel_1.default(labelString, bboxId, this.currentMEI);
|
236
|
+
break;
|
237
|
+
default:
|
238
|
+
return;
|
239
|
+
}
|
240
|
+
if (this.labels.get(label.getElement().id) == undefined) {
|
241
|
+
this.labels.set(label.getElement().id, label);
|
242
|
+
}
|
243
|
+
return label;
|
244
|
+
}
|
245
|
+
highlightNextHarmony(e, active = true) {
|
246
|
+
if (!active) {
|
247
|
+
return;
|
248
|
+
}
|
249
|
+
var pt = new DOMPoint(e.clientX, e.clientY);
|
250
|
+
var rootMatrix = this.labelCanvas.getScreenCTM().inverse();
|
251
|
+
pt = pt.matrixTransform(rootMatrix);
|
252
|
+
var posx = pt.x;
|
253
|
+
var posy = pt.y;
|
254
|
+
var nextNoteBBox = this.m2s.findScoreTarget(posx, posy);
|
255
|
+
if (nextNoteBBox == undefined) {
|
256
|
+
return;
|
257
|
+
}
|
258
|
+
var el = this.vrvSVG.querySelector("#" + nextNoteBBox.id);
|
259
|
+
if (el.closest(".chord") !== null) {
|
260
|
+
el = el.closest(".chord");
|
261
|
+
}
|
262
|
+
if (!el.classList.contains("marked")) {
|
263
|
+
this.vrvSVG.querySelectorAll(".marked").forEach(m => {
|
264
|
+
var _a;
|
265
|
+
m.classList.remove("marked");
|
266
|
+
(_a = this.interactionOverlay.querySelector("[refId=" + m.id + "]")) === null || _a === void 0 ? void 0 : _a.classList.remove("marked");
|
267
|
+
});
|
268
|
+
el.classList.add("marked");
|
269
|
+
}
|
270
|
+
}
|
271
|
+
/**
|
272
|
+
* modify existing label
|
273
|
+
* @param e
|
274
|
+
* @returns
|
275
|
+
*/
|
276
|
+
modifyLabel(e) {
|
277
|
+
var _a, _b;
|
278
|
+
this.closeModifyWindow();
|
279
|
+
var target = e.target;
|
280
|
+
if (target.id === "") {
|
281
|
+
var refId = (_a = target.closest("[refId]")) === null || _a === void 0 ? void 0 : _a.getAttribute("refId");
|
282
|
+
if (refId === null)
|
283
|
+
return;
|
284
|
+
target = (_b = this.vrvSVG.querySelector("#" + refId)) === null || _b === void 0 ? void 0 : _b.closest(".harm");
|
285
|
+
}
|
286
|
+
target = target.closest(labelSelectors);
|
287
|
+
target.setAttribute("visibility", "hidden");
|
288
|
+
var targetBBox = target.getBoundingClientRect();
|
289
|
+
var pt = new DOMPoint(targetBBox.x, targetBBox.y);
|
290
|
+
var rootMatrix = this.labelCanvas.getScreenCTM().inverse();
|
291
|
+
pt = pt.matrixTransform(rootMatrix);
|
292
|
+
var posx = pt.x - 5;
|
293
|
+
var posy = pt.y - 5;
|
294
|
+
// prevent double input boxes for same Element
|
295
|
+
this.elementId = target.id;
|
296
|
+
if (this.container.querySelector("*[refElementId=\"" + target.id + "\"]") !== null) {
|
297
|
+
return;
|
298
|
+
}
|
299
|
+
var className = labelClasses.filter(l => target.classList.contains(l))[0]; //assume only one output, therefore alway return idx 0
|
300
|
+
this.createInputBox(posx, posy, target.id, className);
|
301
|
+
}
|
302
|
+
/**
|
303
|
+
* Close the modifier Window and make the hidden Element visible again
|
304
|
+
*/
|
305
|
+
closeModifyWindow() {
|
306
|
+
try {
|
307
|
+
Array.from(this.labelCanvas.children).forEach(c => {
|
308
|
+
c === null || c === void 0 ? void 0 : c.remove();
|
309
|
+
});
|
310
|
+
}
|
311
|
+
catch (_a) { }
|
312
|
+
// clean MEI from empty harm Elements
|
313
|
+
this.currentMEI.querySelectorAll(labelClasses.join(",")).forEach(h => {
|
314
|
+
var _a;
|
315
|
+
if (h.id === "")
|
316
|
+
return;
|
317
|
+
(_a = this.container.querySelector("#" + h.id)) === null || _a === void 0 ? void 0 : _a.setAttribute("visibility", "visible");
|
318
|
+
});
|
319
|
+
}
|
320
|
+
/**
|
321
|
+
* Save label information in current MEI
|
322
|
+
*/
|
323
|
+
submitLabel() {
|
324
|
+
var labelDiv = this.labelCanvas.getElementsByClassName("labelDiv")[0];
|
325
|
+
var text = labelDiv.textContent;
|
326
|
+
var refElementClass = labelClasses.filter(l => this.container.querySelector("#" + labelDiv.closest("g").getAttribute("refElementId")).classList.contains(l))[0]; // assume only one result
|
327
|
+
var label = this.labels.get(labelDiv.closest("g").getAttribute("refElementId"));
|
328
|
+
if (refElementClass === "harm") { // change existing harm
|
329
|
+
let harmLabel = label;
|
330
|
+
harmLabel.modifyLabel(text);
|
331
|
+
//this.currentMEI.getElementById(harmLabel.getElement().id).replaceWith(harmLabel.getElement())
|
332
|
+
}
|
333
|
+
else if (["note", "chord"].some(cn => refElementClass === cn)) { //create new harm
|
334
|
+
let harmLabel = this.setLabel(labelDiv.textContent, labelDiv.closest("g").getAttribute("refElementId"));
|
335
|
+
this.currentMEI.getElementById(harmLabel.getStartId()).closest("measure").append(harmLabel.getElement());
|
336
|
+
}
|
337
|
+
else if (refElementClass === "tempo") { // change existing tempo
|
338
|
+
var tempoLabel = label;
|
339
|
+
tempoLabel.modifyLabel(text);
|
340
|
+
}
|
341
|
+
this.closeModifyWindow();
|
342
|
+
meiOperation.cleanUp(this.currentMEI);
|
343
|
+
var mei = meiConverter.restoreXmlIdTags(this.currentMEI);
|
344
|
+
this.loadDataCallback("", mei, false).then(() => {
|
345
|
+
this.reset();
|
346
|
+
});
|
347
|
+
}
|
348
|
+
createInputBox(posx, posy, targetId, targetClass) {
|
349
|
+
var textGroup = document.createElementNS(constants_1.constants._SVGNS_, "g");
|
350
|
+
textGroup.setAttribute("id", random_1.uuidv4());
|
351
|
+
textGroup.setAttribute("refElementId", targetId);
|
352
|
+
var text = document.createElementNS(constants_1.constants._SVGNS_, "svg");
|
353
|
+
text.classList.add("labelText");
|
354
|
+
var textForeignObject = document.createElementNS(constants_1.constants._SVGNS_, "foreignObject");
|
355
|
+
textForeignObject.classList.add("labelFO");
|
356
|
+
var textDiv = document.createElement("div");
|
357
|
+
textDiv.setAttribute("contenteditable", "true");
|
358
|
+
switch (targetClass) {
|
359
|
+
case "harm":
|
360
|
+
if (this.labels.get(targetId) != undefined) {
|
361
|
+
var t = this.labels.get(targetId).getInput();
|
362
|
+
for (const [key, value] of mappings_1.unicodeToKey.entries()) {
|
363
|
+
t = t.replace(key, value);
|
364
|
+
}
|
365
|
+
textDiv.textContent = t;
|
366
|
+
}
|
367
|
+
else {
|
368
|
+
textDiv.textContent = "";
|
369
|
+
}
|
370
|
+
break;
|
371
|
+
case "tempo":
|
372
|
+
textDiv.textContent = Array.from(this.container.querySelector("#" + targetId).querySelectorAll(".text")).filter(el => /\d+/.test(el.textContent))[0].textContent.match(/\d+/).join("") || "";
|
373
|
+
break;
|
374
|
+
default:
|
375
|
+
return;
|
376
|
+
}
|
377
|
+
textDiv.classList.add("labelDiv");
|
378
|
+
text.append(textForeignObject);
|
379
|
+
this.container.appendChild(textDiv);
|
380
|
+
var rectPadding = 5;
|
381
|
+
text.setAttribute("x", (posx + rectPadding).toString());
|
382
|
+
text.setAttribute("y", (posy).toString());
|
383
|
+
textForeignObject.setAttribute("x", "0");
|
384
|
+
textForeignObject.setAttribute("y", "0");
|
385
|
+
textForeignObject.setAttribute("height", "1000"); //(textDiv.clientHeight + 2 * rectPadding).toString())
|
386
|
+
textForeignObject.setAttribute("width", "1000"); //(textDiv.clientHeight + 2 * rectPadding).toString())
|
387
|
+
this.labelCanvas.appendChild(textGroup);
|
388
|
+
textGroup.appendChild(text);
|
389
|
+
textForeignObject.appendChild(textDiv);
|
390
|
+
// Special Listeners while Editing Harmonies
|
391
|
+
var that = this;
|
392
|
+
textDiv.addEventListener("focus", function () {
|
393
|
+
that.removeListeners();
|
394
|
+
that.musicPlayer.removePlayListener();
|
395
|
+
});
|
396
|
+
textDiv.addEventListener("blur", function () {
|
397
|
+
textDiv.dispatchEvent(new KeyboardEvent("keydown", { "key": "Enter" })); // trigger submitLabel when bluring
|
398
|
+
that.setListeners();
|
399
|
+
that.musicPlayer.setPlayListener();
|
400
|
+
});
|
401
|
+
textDiv.addEventListener("keydown", this.submitLabelHandler);
|
402
|
+
textDiv.addEventListener("keydown", this.typeLabelHandler);
|
403
|
+
textDiv.focus();
|
404
|
+
}
|
405
|
+
getTimestamp(note) {
|
406
|
+
var layer = note.closest("layer");
|
407
|
+
var elements = Array.from(layer.querySelectorAll("*[dur]"));
|
408
|
+
elements = elements.filter((v, i) => i <= elements.indexOf(note));
|
409
|
+
var tstamp = 0;
|
410
|
+
elements.forEach(e => {
|
411
|
+
var dur = parseInt(e.getAttribute("dur"));
|
412
|
+
tstamp += 4 / dur;
|
413
|
+
var dots = e.getAttribute("dots");
|
414
|
+
var add = dur;
|
415
|
+
if (dots !== null) {
|
416
|
+
for (var i = 0; i < parseInt(dots); i++) {
|
417
|
+
add = add / 2;
|
418
|
+
tstamp += add;
|
419
|
+
}
|
420
|
+
}
|
421
|
+
});
|
422
|
+
return tstamp;
|
423
|
+
}
|
424
|
+
reset() {
|
425
|
+
this.setContainerId(this.containerId);
|
426
|
+
this.addCanvas();
|
427
|
+
this.initLabels();
|
428
|
+
this.removeListeners();
|
429
|
+
this.setListeners();
|
430
|
+
return this;
|
431
|
+
}
|
432
|
+
setm2s(m2s) {
|
433
|
+
this.m2s = m2s;
|
434
|
+
return this;
|
435
|
+
}
|
436
|
+
setCurrentMEI(mei) {
|
437
|
+
this.currentMEI = mei;
|
438
|
+
return this;
|
439
|
+
}
|
440
|
+
setMusicProcessor(musicPlayer) {
|
441
|
+
this.musicPlayer = musicPlayer;
|
442
|
+
return this;
|
443
|
+
}
|
444
|
+
setGlobal(global) {
|
445
|
+
this.isGlobal = global;
|
446
|
+
return this;
|
447
|
+
}
|
448
|
+
getGlobal() {
|
449
|
+
return this.isGlobal;
|
450
|
+
}
|
451
|
+
setLoadDataCallback(loadDataCallback) {
|
452
|
+
this.loadDataCallback = loadDataCallback;
|
453
|
+
return this;
|
454
|
+
}
|
455
|
+
setContainerId(id) {
|
456
|
+
this.containerId = id;
|
457
|
+
this.container = document.getElementById(id);
|
458
|
+
this.vrvSVG = cq.getVrvSVG(id);
|
459
|
+
this.interactionOverlay = cq.getInteractOverlay(id);
|
460
|
+
return this;
|
461
|
+
}
|
462
|
+
}
|
463
|
+
exports.default = LabelHandler;
|
@@ -0,0 +1,97 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const coordinates = require("../utils/coordinates");
|
4
|
+
const cq = require("../utils/convenienceQueries");
|
5
|
+
const interactjs_1 = require("interactjs");
|
6
|
+
/**
|
7
|
+
* Class that handles insert mode, events, and actions.
|
8
|
+
*/
|
9
|
+
class NoteDragHandler {
|
10
|
+
constructor(containerId) {
|
11
|
+
this.setContainerId(containerId);
|
12
|
+
}
|
13
|
+
setListeners() {
|
14
|
+
var that = this;
|
15
|
+
this.noteDragListener = interactjs_1.default("#" + this.containerId + " #interactionOverlay .notehead rect")
|
16
|
+
.draggable({
|
17
|
+
startAxis: "y",
|
18
|
+
lockAxis: "y",
|
19
|
+
listeners: {
|
20
|
+
move: this.dragNote.bind(this),
|
21
|
+
end(event) {
|
22
|
+
that.deleteTempDistances();
|
23
|
+
that.insertCallback(that.newNote, true);
|
24
|
+
}
|
25
|
+
},
|
26
|
+
modifiers: [
|
27
|
+
interactjs_1.default.modifiers.restrictRect({
|
28
|
+
endOnly: true
|
29
|
+
})
|
30
|
+
]
|
31
|
+
});
|
32
|
+
}
|
33
|
+
removeListeners() {
|
34
|
+
var _a;
|
35
|
+
(_a = this.noteDragListener) === null || _a === void 0 ? void 0 : _a.unset();
|
36
|
+
}
|
37
|
+
resetListeners() {
|
38
|
+
this.removeListeners();
|
39
|
+
this.setListeners();
|
40
|
+
return this;
|
41
|
+
}
|
42
|
+
deleteTempDistances() {
|
43
|
+
var _a;
|
44
|
+
(_a = cq.getInteractOverlay(this.containerId)) === null || _a === void 0 ? void 0 : _a.querySelectorAll("*[distY]").forEach(d => {
|
45
|
+
d.removeAttribute("distY");
|
46
|
+
d.classList.remove("moving");
|
47
|
+
});
|
48
|
+
}
|
49
|
+
dragNote(e) {
|
50
|
+
var _a;
|
51
|
+
var noteHeadBBox = e.target;
|
52
|
+
this.noteDragEvent = new MouseEvent("draggingNote", e);
|
53
|
+
noteHeadBBox.dispatchEvent(this.noteDragEvent);
|
54
|
+
var refNote = cq.getVrvSVG(this.containerId).querySelector("#" + noteHeadBBox.parentElement.getAttribute("refId")).closest(".note");
|
55
|
+
var note = cq.getInteractOverlay(this.containerId).querySelector("*[refId=\"" + refNote.id + "\"] rect");
|
56
|
+
if (!noteHeadBBox.classList.contains("moving"))
|
57
|
+
noteHeadBBox.classList.add("moving");
|
58
|
+
var headPos = this.newPos(noteHeadBBox, e);
|
59
|
+
this.m2s.defineNote(headPos.x, headPos.y, {});
|
60
|
+
this.newNote = this.m2s.getNewNote();
|
61
|
+
if (refNote.closest(".chord") !== null) {
|
62
|
+
this.newNote.chordElement = refNote.closest(".chord");
|
63
|
+
(_a = this.currentMEI.querySelector("#" + refNote.id)) === null || _a === void 0 ? void 0 : _a.remove();
|
64
|
+
}
|
65
|
+
}
|
66
|
+
newPos(target, e) {
|
67
|
+
var pt = coordinates.transformToDOMMatrixCoordinates(e.clientX, e.clientY, target.closest("*[viewBox]"));
|
68
|
+
var edy = pt.y;
|
69
|
+
var ptDist = coordinates.transformToDOMMatrixCoordinates(target.getBoundingClientRect().x, target.getBoundingClientRect().y, target.closest("*[viewBox]"));
|
70
|
+
var distY = (parseFloat(target.getAttribute('distY'))) || edy - ptDist.y;
|
71
|
+
target.setAttribute("distY", distY.toString());
|
72
|
+
target.setAttribute("y", (edy - distY).toString());
|
73
|
+
return { x: pt.x, y: pt.y };
|
74
|
+
}
|
75
|
+
//////////////// GETTER/ SETTER ////////////
|
76
|
+
setMusicProcessor(musicPlayer) {
|
77
|
+
this.musicPlayer = musicPlayer;
|
78
|
+
return this;
|
79
|
+
}
|
80
|
+
setCurrentMEI(xmlDoc) {
|
81
|
+
this.currentMEI = xmlDoc;
|
82
|
+
return this;
|
83
|
+
}
|
84
|
+
setm2s(m2s) {
|
85
|
+
this.m2s = m2s;
|
86
|
+
return this;
|
87
|
+
}
|
88
|
+
setInsertCallback(insertCallback) {
|
89
|
+
this.insertCallback = insertCallback;
|
90
|
+
return this;
|
91
|
+
}
|
92
|
+
setContainerId(id) {
|
93
|
+
this.containerId = id;
|
94
|
+
return this;
|
95
|
+
}
|
96
|
+
}
|
97
|
+
exports.default = NoteDragHandler;
|