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,535 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const coordinates = require("../utils/coordinates");
|
4
|
+
const cq = require("../utils/convenienceQueries");
|
5
|
+
const mappings_1 = require("../utils/mappings");
|
6
|
+
const marked = "marked";
|
7
|
+
class ClickModeHandler {
|
8
|
+
constructor() {
|
9
|
+
this.isSelecting = false;
|
10
|
+
this.selectDist = 0;
|
11
|
+
this.dragOnce = false;
|
12
|
+
this.shiftPressed = false;
|
13
|
+
this.selectEndEvent = new Event("selectEnd");
|
14
|
+
/**
|
15
|
+
* Event handler for inserting Notes
|
16
|
+
*/
|
17
|
+
this.insertNoteHandler = (function insertNoteHandler(e) {
|
18
|
+
this.insertNote(e);
|
19
|
+
}).bind(this);
|
20
|
+
/**
|
21
|
+
* Hide the phantom element for the cursor.
|
22
|
+
*/
|
23
|
+
this.hideCursor = function () {
|
24
|
+
if (this.interactionOverlay.querySelector(".moving"))
|
25
|
+
return;
|
26
|
+
this.container.querySelectorAll("#phantomCanvas > *").forEach(ph => {
|
27
|
+
ph.setAttribute("visibility", "hidden");
|
28
|
+
}); // make phantoms invisible
|
29
|
+
}.bind(this);
|
30
|
+
/**
|
31
|
+
* Show phantom element for cursor.
|
32
|
+
*/
|
33
|
+
this.showCursor = function () {
|
34
|
+
this.container.querySelectorAll("#phantomCanvas > *").forEach(ph => ph.setAttribute("visibility", "visible")); // make phantoms invisible
|
35
|
+
}.bind(this);
|
36
|
+
/**
|
37
|
+
* Handler for {@link mouseOverChord}
|
38
|
+
*/
|
39
|
+
this.mouseOverChordHandler = (function mouseOverHandler(e) {
|
40
|
+
this.mouseOverChord(e);
|
41
|
+
}).bind(this);
|
42
|
+
// SELECTION STUFF
|
43
|
+
this.clickSelectHandler = (function clickSelectHandler(e) {
|
44
|
+
this.clickSelect(e);
|
45
|
+
}).bind(this);
|
46
|
+
/**
|
47
|
+
* Initialize start coordinates of selecting rectangle.
|
48
|
+
* {@link getSelectCoordsHandler} will compute distances on dragging the mouse to decide on initialisation of selection.
|
49
|
+
*/
|
50
|
+
this.selStartHandler = (function selStartHandler(e) {
|
51
|
+
this.selectStartX = this.selectStartX || e.clientX;
|
52
|
+
this.selectStartY = this.selectStartY || e.clientY;
|
53
|
+
}).bind(this);
|
54
|
+
this.selectingHandler = (function selectingHandler(e) {
|
55
|
+
this.selecting(e);
|
56
|
+
}).bind(this);
|
57
|
+
/**
|
58
|
+
* Handler for {@link selEnd}.
|
59
|
+
*/
|
60
|
+
this.selEndHandler = (function selEndHandler(e) {
|
61
|
+
this.selEnd(e);
|
62
|
+
}).bind(this);
|
63
|
+
/**
|
64
|
+
* Handler for {@link getSelectCoords}
|
65
|
+
*/
|
66
|
+
this.getSelectCoordsHandler = (function getSelectCoordsHandler(e) {
|
67
|
+
this.getSelectCoords(e);
|
68
|
+
}).bind(this);
|
69
|
+
/**
|
70
|
+
* Handle shift presses and set shiftPressed flag.
|
71
|
+
*/
|
72
|
+
this.shiftKeyHandler = (function shiftKeyHandler(e) {
|
73
|
+
//e.preventDefault()
|
74
|
+
if (e.key === "Shift") {
|
75
|
+
if (e.type === "keydown") {
|
76
|
+
this.shiftPressed = true;
|
77
|
+
}
|
78
|
+
if (e.type === "keyup") {
|
79
|
+
this.shiftPressed = false;
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}).bind(this);
|
83
|
+
}
|
84
|
+
setListeners() {
|
85
|
+
// Insert Notation Listeners
|
86
|
+
this.interactionOverlay.addEventListener("mouseup", this.insertNoteHandler);
|
87
|
+
this.interactionOverlay.addEventListener("mousemove", this.mouseOverChordHandler);
|
88
|
+
this.interactionOverlay.querySelectorAll("#scoreRects > *").forEach(sr => {
|
89
|
+
if (["clef", "meterSig", "keySig", "rest", "notehead", "harm",].some(c => sr.classList.contains(c))) {
|
90
|
+
sr.addEventListener("mouseover", this.hideCursor);
|
91
|
+
}
|
92
|
+
else {
|
93
|
+
sr.addEventListener("mouseover", this.showCursor);
|
94
|
+
}
|
95
|
+
});
|
96
|
+
//Selection Listeners
|
97
|
+
this.interactionOverlay.addEventListener("mousedown", this.selStartHandler);
|
98
|
+
this.interactionOverlay.addEventListener("mousemove", this.selectingHandler);
|
99
|
+
this.interactionOverlay.addEventListener("mousemove", this.getSelectCoordsHandler);
|
100
|
+
this.interactionOverlay.addEventListener("mouseup", this.selEndHandler);
|
101
|
+
this.interactionOverlay.querySelectorAll(".notehead, .rest").forEach(el => el.addEventListener("click", this.clickSelectHandler));
|
102
|
+
//shiftkey for special function
|
103
|
+
document.addEventListener("keydown", this.shiftKeyHandler);
|
104
|
+
document.addEventListener("keyup", this.shiftKeyHandler);
|
105
|
+
//hide or show cursor based on position
|
106
|
+
this.interactionOverlay.querySelectorAll("#manipulatorCanvas *, #annotationCanvas *").forEach(sr => {
|
107
|
+
sr.addEventListener("mouseover", this.hideCursor);
|
108
|
+
sr.addEventListener("mouseleave", this.showCursor);
|
109
|
+
});
|
110
|
+
// Listener just for staves
|
111
|
+
var staves = this.interactionOverlay.querySelectorAll(".staffLine");
|
112
|
+
Array.from(staves).forEach(element => {
|
113
|
+
element.addEventListener('mouseup', this.insertNoteHandler);
|
114
|
+
});
|
115
|
+
}
|
116
|
+
removeListeners() {
|
117
|
+
this.interactionOverlay.removeEventListener("mousedown", this.selStartHandler);
|
118
|
+
this.interactionOverlay.removeEventListener("mousemove", this.selectingHandler);
|
119
|
+
this.interactionOverlay.removeEventListener("mousemove", this.getSelectCoordsHandler);
|
120
|
+
this.interactionOverlay.removeEventListener("mouseup", this.selEndHandler);
|
121
|
+
this.interactionOverlay.querySelectorAll(".notehead, .rest").forEach(el => el.removeEventListener("click", this.clickSelectHandler));
|
122
|
+
this.interactionOverlay.removeEventListener("mouseup", this.insertNoteHandler);
|
123
|
+
this.interactionOverlay.removeEventListener("mousemove", this.mouseOverChordHandler);
|
124
|
+
if (this.annotations != undefined) {
|
125
|
+
var highLightElements = this.annotations.getAnnotationCanvas().querySelectorAll(".highlightChord");
|
126
|
+
Array.from(highLightElements).forEach(el => {
|
127
|
+
el.remove();
|
128
|
+
});
|
129
|
+
}
|
130
|
+
document.removeEventListener("keydown", this.shiftKeyHandler);
|
131
|
+
document.removeEventListener("keyup", this.shiftKeyHandler);
|
132
|
+
this.container.querySelectorAll(".highlighted").forEach((c) => {
|
133
|
+
c.classList.remove("highlighted");
|
134
|
+
});
|
135
|
+
this.interactionOverlay.querySelectorAll("#scoreRects > *").forEach(sr => {
|
136
|
+
if (["clef", "meterSig", "keySig", "rest", "notehead", "harm"].some(c => sr.classList.contains(c))) {
|
137
|
+
sr.removeEventListener("mouseover", this.hideCursor);
|
138
|
+
}
|
139
|
+
else {
|
140
|
+
sr.removeEventListener("mouseover", this.showCursor);
|
141
|
+
}
|
142
|
+
});
|
143
|
+
// Listener just for staves
|
144
|
+
var staves = this.interactionOverlay.querySelectorAll(".staffLine");
|
145
|
+
Array.from(staves).forEach(element => {
|
146
|
+
element.removeEventListener('mouseup', this.insertNoteHandler);
|
147
|
+
});
|
148
|
+
}
|
149
|
+
resetListeners() {
|
150
|
+
this.removeListeners();
|
151
|
+
this.setListeners();
|
152
|
+
}
|
153
|
+
/**
|
154
|
+
* Insert a note when mouseup is fires based on mouse position.
|
155
|
+
* @param e
|
156
|
+
* @returns
|
157
|
+
*/
|
158
|
+
insertNote(e) {
|
159
|
+
var _a;
|
160
|
+
// when mouseup is fired, selEndHandler and insertNotehandler are alled.
|
161
|
+
// The isSelecting flag is set to true as soon as a selection startet, only after that an insertion of a note should be possible
|
162
|
+
if (this.isSelecting) {
|
163
|
+
this.isSelecting = false;
|
164
|
+
return;
|
165
|
+
}
|
166
|
+
var t = e.target;
|
167
|
+
if (cq.getContainer(this.containerId).querySelectorAll(`.${marked}`).length > 1 && !this.shiftPressed) {
|
168
|
+
cq.getContainer(this.containerId).querySelectorAll(`.${marked}`).forEach(m => m.classList.remove(marked));
|
169
|
+
return; // when more than one element is marked is likely to remove marked status of all notes
|
170
|
+
}
|
171
|
+
if (cq.getContainer(this.containerId).classList.contains("annotMode"))
|
172
|
+
return; // prevent selecting when resizing annotation objects
|
173
|
+
if (cq.getContainer(this.containerId).querySelector("#phantomNote").getAttribute("visibility") === "hidden")
|
174
|
+
return; //the cursor is possibly somewhere where no note input is possible
|
175
|
+
if (cq.getContainer(this.containerId).querySelector("[contenteditable=true]"))
|
176
|
+
return;
|
177
|
+
e.preventDefault();
|
178
|
+
// when mouse is over other interactable elements discard this event
|
179
|
+
if (["clef", "meterSig", "keySig", "rest", "notehead", "manipulator"].some(c => {
|
180
|
+
let parentCondition = t.parentElement.classList.contains(c);
|
181
|
+
let layerCondition = false;
|
182
|
+
if (!t.closest(".activeLayer")) {
|
183
|
+
layerCondition = true;
|
184
|
+
}
|
185
|
+
return parentCondition && layerCondition;
|
186
|
+
})) {
|
187
|
+
this.hideCursor();
|
188
|
+
return;
|
189
|
+
}
|
190
|
+
if (!this.phantomElementHandler.getIsTrackingMouse()) {
|
191
|
+
return;
|
192
|
+
}
|
193
|
+
if (this.musicPlayer.getIsPlaying() === true) {
|
194
|
+
return;
|
195
|
+
} // getIsPlaying could also be undefined
|
196
|
+
// Define position of mouse and which note to set
|
197
|
+
var pospt = coordinates.transformToDOMMatrixCoordinates(e.clientX, e.clientY, this.vrvSVG);
|
198
|
+
var posx = pospt.x;
|
199
|
+
var posy = pospt.y;
|
200
|
+
var target = e.target;
|
201
|
+
var options = {};
|
202
|
+
if (target.classList.contains("staffLine")) {
|
203
|
+
options["staffLineId"] = target.id;
|
204
|
+
}
|
205
|
+
if ((_a = this.interactionOverlay.querySelector("#phantomNote")) === null || _a === void 0 ? void 0 : _a.classList.contains("onChord")) {
|
206
|
+
options["targetChord"] = this.findScoreTarget(posx, posy);
|
207
|
+
}
|
208
|
+
//this.m2s.defineNote(e.pageX, e.pageY, options);
|
209
|
+
this.m2s.defineNote(posx, posy, options);
|
210
|
+
var newNote = this.m2s.getNewNote();
|
211
|
+
if (newNote == undefined)
|
212
|
+
return; //Eingabemaske in Chrome: zusätzliche Notenlinien in Noteneditor #10
|
213
|
+
var meiDoc = this.m2s.getCurrentMei();
|
214
|
+
var pitchExists = false;
|
215
|
+
// do not insert same note more than once in chord
|
216
|
+
if (newNote.chordElement) {
|
217
|
+
var chordEl = meiDoc.getElementById(newNote.chordElement.id);
|
218
|
+
if (chordEl.getAttribute("pname") === newNote.pname && chordEl.getAttribute("oct") === newNote.oct) {
|
219
|
+
pitchExists = true;
|
220
|
+
}
|
221
|
+
else {
|
222
|
+
for (let c of chordEl.children) {
|
223
|
+
if (c.getAttribute("pname") === newNote.pname && c.getAttribute("oct") === newNote.oct) {
|
224
|
+
pitchExists = true;
|
225
|
+
break;
|
226
|
+
}
|
227
|
+
}
|
228
|
+
}
|
229
|
+
}
|
230
|
+
if (!pitchExists) {
|
231
|
+
var replace = true; //(this.container.querySelector("#insertToggle") as HTMLInputElement).checked && newNote.chordElement == undefined
|
232
|
+
this.insertCallback(this.m2s.getNewNote(), replace).then(() => {
|
233
|
+
this.musicPlayer.generateTone(this.m2s.getNewNote());
|
234
|
+
}).catch(() => {
|
235
|
+
//alert("Your bar is to small")
|
236
|
+
});
|
237
|
+
}
|
238
|
+
}
|
239
|
+
/**
|
240
|
+
* Check if mouse is over a chord to snap cursor and define new note within a chord elemnt
|
241
|
+
*/
|
242
|
+
mouseOverChord(e) {
|
243
|
+
var _a;
|
244
|
+
if (!this.phantomElementHandler.getIsTrackingMouse()) {
|
245
|
+
return;
|
246
|
+
}
|
247
|
+
var coords = coordinates.transformToDOMMatrixCoordinates(e.clientX, e.clientY, this.interactionOverlay);
|
248
|
+
var posx = coords.x;
|
249
|
+
var posy = coords.y;
|
250
|
+
var elementToHighlight = this.findScoreTarget(posx, posy);
|
251
|
+
if (elementToHighlight == undefined || elementToHighlight.closest(".mRest") !== null || elementToHighlight.closest(".rest") !== null) {
|
252
|
+
return;
|
253
|
+
}
|
254
|
+
//if (this.currentElementToHighlight !== elementToHighlight) {
|
255
|
+
//update focussed layer if element and layer do not match
|
256
|
+
if (elementToHighlight.closest(".layer").id !== ((_a = this.m2s.getMouseEnterElementByName("layer")) === null || _a === void 0 ? void 0 : _a.id) && this.m2s.getMouseEnterElementByName("layer") !== null) {
|
257
|
+
this.m2s.setMouseEnterElements(elementToHighlight);
|
258
|
+
}
|
259
|
+
//snap note to closest Chord
|
260
|
+
var phantom = this.interactionOverlay.querySelector("#phantomNote");
|
261
|
+
var cx = parseFloat(phantom.getAttribute("cx"));
|
262
|
+
var bboxElement = this.interactionOverlay.querySelector("[refId=" + elementToHighlight.id + "]");
|
263
|
+
var ptLeft = new DOMPoint(bboxElement.getBoundingClientRect().left, 0);
|
264
|
+
var ptRight = new DOMPoint(bboxElement.getBoundingClientRect().right, 0);
|
265
|
+
var vrvSVG = this.interactionOverlay;
|
266
|
+
var left = ptLeft.matrixTransform(vrvSVG.getScreenCTM().inverse()).x;
|
267
|
+
var right = ptRight.matrixTransform(vrvSVG.getScreenCTM().inverse()).x;
|
268
|
+
//snap only when within boundaries of target Chord
|
269
|
+
if (cx > left && cx < right) {
|
270
|
+
var snapTarget;
|
271
|
+
var snapTargetBBox;
|
272
|
+
var phantomSnapX;
|
273
|
+
var targetwidth;
|
274
|
+
var snapCoord;
|
275
|
+
snapTarget = bboxElement;
|
276
|
+
snapTargetBBox = snapTarget.getBoundingClientRect();
|
277
|
+
snapCoord = snapTargetBBox.x + snapTargetBBox.width / 2;
|
278
|
+
let snappt = new DOMPoint(snapCoord, 0);
|
279
|
+
phantomSnapX = snappt.matrixTransform(vrvSVG.getScreenCTM().inverse()).x;
|
280
|
+
// if (elementToHighlight.querySelector(".chord") !== null) {
|
281
|
+
// console.log(phantomSnapX)
|
282
|
+
// }
|
283
|
+
phantom.setAttribute("cx", phantomSnapX.toString());
|
284
|
+
if (!phantom.classList.contains("onChord")) {
|
285
|
+
phantom.classList.add("onChord");
|
286
|
+
phantom.classList.add("l" + elementToHighlight.closest(".layer").getAttribute("n"));
|
287
|
+
if (!elementToHighlight.classList.contains("chord")) {
|
288
|
+
elementToHighlight.classList.add("highlighted");
|
289
|
+
}
|
290
|
+
else {
|
291
|
+
elementToHighlight.querySelectorAll(".note").forEach((c) => {
|
292
|
+
c.classList.add("highlighted");
|
293
|
+
});
|
294
|
+
}
|
295
|
+
}
|
296
|
+
}
|
297
|
+
else {
|
298
|
+
for (const [key, value] of phantom.classList.entries()) {
|
299
|
+
if (value.indexOf("l") === 0) {
|
300
|
+
phantom.classList.remove(value);
|
301
|
+
}
|
302
|
+
}
|
303
|
+
phantom.classList.remove("onChord");
|
304
|
+
phantom.setAttribute("fill", "black");
|
305
|
+
this.container.querySelectorAll(".highlighted").forEach(h => {
|
306
|
+
h.classList.remove("highlighted");
|
307
|
+
});
|
308
|
+
}
|
309
|
+
this.currentElementToHighlight = elementToHighlight;
|
310
|
+
//}
|
311
|
+
}
|
312
|
+
/**
|
313
|
+
* Find Score Element nearest to given Position (e.g. Mouse)
|
314
|
+
* @param posx client position
|
315
|
+
* @param posy client position
|
316
|
+
* @returns
|
317
|
+
*/
|
318
|
+
findScoreTarget(posx, posy) {
|
319
|
+
var _a;
|
320
|
+
const nextNote = this.m2s.findScoreTarget(posx, posy);
|
321
|
+
if (nextNote) {
|
322
|
+
var el = ((_a = this.vrvSVG.querySelector("#" + nextNote.id)) === null || _a === void 0 ? void 0 : _a.closest(".chord")) || this.vrvSVG.querySelector("#" + nextNote.id);
|
323
|
+
if (el.classList.contains("notehead")) {
|
324
|
+
el = el.parentElement;
|
325
|
+
}
|
326
|
+
return el;
|
327
|
+
}
|
328
|
+
return;
|
329
|
+
}
|
330
|
+
clickSelect(e) {
|
331
|
+
if (!this.shiftPressed) {
|
332
|
+
cq.getVrvSVG(this.containerId).querySelectorAll(".marked").forEach(m => m.classList.remove(marked));
|
333
|
+
}
|
334
|
+
const t = e.target;
|
335
|
+
const notehead = cq.getVrvSVG(this.containerId).querySelector(`#${t.parentElement.getAttribute("refId")}`);
|
336
|
+
notehead === null || notehead === void 0 ? void 0 : notehead.classList.add(marked);
|
337
|
+
const note = notehead.closest(".note");
|
338
|
+
if (note) {
|
339
|
+
note.classList.add(marked);
|
340
|
+
this.scoreGraph.setCurrentNodeById(note.id);
|
341
|
+
}
|
342
|
+
}
|
343
|
+
selStart(e) {
|
344
|
+
e.preventDefault();
|
345
|
+
if (!this.isSelecting)
|
346
|
+
return;
|
347
|
+
if (cq.getContainer(this.containerId).classList.contains("annotMode")) {
|
348
|
+
this.selEnd(e);
|
349
|
+
return;
|
350
|
+
}
|
351
|
+
//var pt = coordinates.transformToDOMMatrixCoordinates(d3.event.sourceEvent.clientX, d3.event.sourceEvent.clientY, cq.getInteractOverlay(this.containerId))
|
352
|
+
var pt = coordinates.transformToDOMMatrixCoordinates(e.clientX, e.clientY, cq.getInteractOverlay(this.containerId));
|
353
|
+
this.initialSelectX = pt.x; //d3.event.x
|
354
|
+
this.initialSelectY = pt.y; //d3.event.y
|
355
|
+
if (!document.getElementById(this.containerId).classList.contains("harmonyMode") && !this.shiftPressed) { //!this.harmonyHandler.getGlobal()){
|
356
|
+
this.m2s.getNoteBBoxes().forEach(bb => {
|
357
|
+
let note = this.vrvSVG.querySelector("#" + bb.id);
|
358
|
+
note.classList.remove(marked);
|
359
|
+
});
|
360
|
+
}
|
361
|
+
this.initRect(this.initialSelectX, this.initialSelectY);
|
362
|
+
this.isSelecting = true;
|
363
|
+
}
|
364
|
+
selecting(e) {
|
365
|
+
e.preventDefault();
|
366
|
+
if (document.getElementById(this.containerId).classList.contains("annotMode"))
|
367
|
+
return; // prevent selecting when resizing annotation objects
|
368
|
+
if (!this.isSelecting)
|
369
|
+
return;
|
370
|
+
const pt = coordinates.transformToDOMMatrixCoordinates(e.clientX, e.clientY, cq.getInteractOverlay(this.containerId));
|
371
|
+
const curX = pt.x;
|
372
|
+
const curY = pt.y;
|
373
|
+
const newX = curX < this.initialSelectX ? curX : this.initialSelectX;
|
374
|
+
const newY = curY < this.initialSelectY ? curY : this.initialSelectY;
|
375
|
+
const width = curX < this.initialSelectX ? this.initialSelectX - curX : curX - this.initialSelectX;
|
376
|
+
const height = curY < this.initialSelectY ? this.initialSelectY - curY : curY - this.initialSelectY;
|
377
|
+
this.updateRect(newX, newY, width, height);
|
378
|
+
const rect = this.interactionOverlay.querySelector("#selectRect");
|
379
|
+
const rectpt = coordinates.getDOMMatrixCoordinates(rect, this.vrvSVG);
|
380
|
+
const rectHeightpt = rectpt.height;
|
381
|
+
const rectWidthpt = rectpt.width;
|
382
|
+
const rx = rectpt.x;
|
383
|
+
const ry = rectpt.y;
|
384
|
+
const noteBBoxes = this.m2s.getNoteBBoxes();
|
385
|
+
noteBBoxes.forEach(bb => {
|
386
|
+
const note = cq.getVrvSVG(this.containerId).querySelector("#" + bb.id);
|
387
|
+
const stem = note.querySelector(".stem");
|
388
|
+
const accid = note.querySelector(".accid");
|
389
|
+
if (bb.x >= rx &&
|
390
|
+
//bb.x <= rx + rectBBox.width &&
|
391
|
+
bb.x <= rx + rectWidthpt &&
|
392
|
+
bb.y >= ry &&
|
393
|
+
//bb.y <= ry + rectBBox.height
|
394
|
+
bb.y <= ry + rectHeightpt) {
|
395
|
+
note.classList.add(marked);
|
396
|
+
if (stem !== null)
|
397
|
+
stem.classList.add(marked);
|
398
|
+
const chord = note.closest(".chord");
|
399
|
+
if (chord !== null) {
|
400
|
+
//if(!chord.classList.contains(marked))
|
401
|
+
const noteArr = Array.from(chord.querySelectorAll(".note"));
|
402
|
+
if (noteArr.every(c => c.classList.contains(marked)) && noteArr.length > 0) {
|
403
|
+
chord.classList.add(marked);
|
404
|
+
}
|
405
|
+
}
|
406
|
+
}
|
407
|
+
else if (!this.shiftPressed) {
|
408
|
+
note.classList.remove(marked);
|
409
|
+
stem === null || stem === void 0 ? void 0 : stem.classList.remove(marked);
|
410
|
+
accid === null || accid === void 0 ? void 0 : accid.classList.remove(marked);
|
411
|
+
const chord = note.closest(".chord");
|
412
|
+
chord === null || chord === void 0 ? void 0 : chord.classList.remove(marked);
|
413
|
+
}
|
414
|
+
});
|
415
|
+
}
|
416
|
+
/**
|
417
|
+
* Ends selection. Resets all flags and delets selectRect
|
418
|
+
* @param e
|
419
|
+
* @returns
|
420
|
+
*/
|
421
|
+
selEnd(e) {
|
422
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
423
|
+
e.preventDefault();
|
424
|
+
this.dragOnce = false;
|
425
|
+
this.selectStartX = undefined;
|
426
|
+
this.selectStartY = undefined;
|
427
|
+
this.selectDist = 0;
|
428
|
+
this.isSelecting = false;
|
429
|
+
if (document.getElementById(this.containerId).classList.contains("annotMode"))
|
430
|
+
return; // prevent selecting when resizing annotation objects
|
431
|
+
var selectRect = cq.getInteractOverlay(this.containerId).querySelector("#selectRect");
|
432
|
+
if (selectRect !== null && (selectRect === null || selectRect === void 0 ? void 0 : selectRect.getAttribute("width")) !== "0" && (selectRect === null || selectRect === void 0 ? void 0 : selectRect.getAttribute("height")) !== "0") {
|
433
|
+
document.dispatchEvent(this.selectEndEvent);
|
434
|
+
}
|
435
|
+
selectRect === null || selectRect === void 0 ? void 0 : selectRect.remove();
|
436
|
+
var firstMarkedNote = (_a = this.vrvSVG.querySelector(".chord.marked, .note.marked, .rest.marked")) === null || _a === void 0 ? void 0 : _a.id;
|
437
|
+
var meiNote = this.m2s.getCurrentMei().getElementById(firstMarkedNote);
|
438
|
+
(_c = (_b = document.getElementById(this.containerId)) === null || _b === void 0 ? void 0 : _b.querySelectorAll(".lastAdded")) === null || _c === void 0 ? void 0 : _c.forEach(la => la.classList.remove("lastAdded"));
|
439
|
+
if ((firstMarkedNote === null || firstMarkedNote === void 0 ? void 0 : firstMarkedNote.length) > 0) {
|
440
|
+
(_d = document.getElementById(this.containerId)) === null || _d === void 0 ? void 0 : _d.querySelectorAll("#noteGroup *, #dotGroup *, #modGroup *, #articGroup *").forEach(b => b.classList.remove("selected"));
|
441
|
+
//select buttons for given note state
|
442
|
+
var modBtnId = this.container.querySelector("#customToolbar #articGroup") !== null ? "artic" : "accid";
|
443
|
+
(_f = (_e = document.getElementById(this.containerId)) === null || _e === void 0 ? void 0 : _e.querySelector("#" + mappings_1.attrToAccidButtonId.get(meiNote === null || meiNote === void 0 ? void 0 : meiNote.getAttribute(modBtnId)))) === null || _f === void 0 ? void 0 : _f.classList.add("selected");
|
444
|
+
if ((meiNote === null || meiNote === void 0 ? void 0 : meiNote.closest("chord")) !== null) {
|
445
|
+
meiNote = meiNote.closest("chord");
|
446
|
+
}
|
447
|
+
(_h = (_g = document.getElementById(this.containerId)) === null || _g === void 0 ? void 0 : _g.querySelector("#" + mappings_1.numToNoteButtonId.get(meiNote === null || meiNote === void 0 ? void 0 : meiNote.getAttribute("dur")))) === null || _h === void 0 ? void 0 : _h.classList.add("selected");
|
448
|
+
(_k = (_j = document.getElementById(this.containerId)) === null || _j === void 0 ? void 0 : _j.querySelector("#" + mappings_1.numToDotButtonId.get(meiNote === null || meiNote === void 0 ? void 0 : meiNote.getAttribute("dots")))) === null || _k === void 0 ? void 0 : _k.classList.add("selected");
|
449
|
+
}
|
450
|
+
}
|
451
|
+
/**
|
452
|
+
* Initialize selectRect.
|
453
|
+
* @param x start x
|
454
|
+
* @param y start y
|
455
|
+
*/
|
456
|
+
initRect(x, y) {
|
457
|
+
const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
458
|
+
rect.setAttribute("x", x.toString());
|
459
|
+
rect.setAttribute("y", y.toString());
|
460
|
+
rect.setAttribute("width", "0");
|
461
|
+
rect.setAttribute("height", "0");
|
462
|
+
rect.setAttribute("id", "selectRect");
|
463
|
+
rect.setAttribute("stroke", "black");
|
464
|
+
rect.setAttribute("stroke-width", "1px");
|
465
|
+
rect.setAttribute("fill", "none");
|
466
|
+
this.interactionOverlay.appendChild(rect);
|
467
|
+
}
|
468
|
+
/**
|
469
|
+
* Update size of selectRect.
|
470
|
+
* @param newX x posiiton of mouse cursor
|
471
|
+
* @param newY y position of mouse cursor
|
472
|
+
* @param currentWidth
|
473
|
+
* @param currentHeight
|
474
|
+
*/
|
475
|
+
updateRect(newX, newY, currentWidth, currentHeight) {
|
476
|
+
const rect = this.interactionOverlay.querySelector("#selectRect");
|
477
|
+
rect.setAttribute("x", newX.toString());
|
478
|
+
rect.setAttribute("y", newY.toString());
|
479
|
+
rect.setAttribute("width", currentWidth.toString());
|
480
|
+
rect.setAttribute("height", currentHeight.toString());
|
481
|
+
}
|
482
|
+
/**
|
483
|
+
* Compute coordinates to determine if a selection should be initialized.
|
484
|
+
* Starts selection once if distance > 10.
|
485
|
+
* This is important to distinguish between inserting a note, drawing the selectRect and selecting one element by click.
|
486
|
+
* @param e MouseEvent
|
487
|
+
*/
|
488
|
+
getSelectCoords(e) {
|
489
|
+
this.selectDist = Math.sqrt(Math.abs(e.clientX - this.selectStartX) ** 2 + Math.abs(e.clientY - this.selectStartY) ** 2);
|
490
|
+
if (this.selectDist > 10) {
|
491
|
+
this.isSelecting = true;
|
492
|
+
if (!this.dragOnce) {
|
493
|
+
this.dragOnce = true;
|
494
|
+
this.selStart(e);
|
495
|
+
}
|
496
|
+
}
|
497
|
+
}
|
498
|
+
///// GETTER / SETTER////////////////
|
499
|
+
setm2s(m2s) {
|
500
|
+
this.m2s = m2s;
|
501
|
+
return this;
|
502
|
+
}
|
503
|
+
setMusicProcessor(musicPlayer) {
|
504
|
+
this.musicPlayer = musicPlayer;
|
505
|
+
return this;
|
506
|
+
}
|
507
|
+
setScoreGraph(sg) {
|
508
|
+
this.scoreGraph = sg;
|
509
|
+
return this;
|
510
|
+
}
|
511
|
+
setContainerId(id) {
|
512
|
+
this.containerId = id;
|
513
|
+
this.vrvSVG = cq.getVrvSVG(id);
|
514
|
+
this.interactionOverlay = cq.getInteractOverlay(id);
|
515
|
+
this.container = document.getElementById(id);
|
516
|
+
return this;
|
517
|
+
}
|
518
|
+
setAnnotations(annotations) {
|
519
|
+
this.annotations = annotations;
|
520
|
+
return this;
|
521
|
+
}
|
522
|
+
setInsertCallback(insertCallback) {
|
523
|
+
this.insertCallback = insertCallback;
|
524
|
+
return this;
|
525
|
+
}
|
526
|
+
setDeleteCallback(deleteCallback) {
|
527
|
+
this.deleteCallback = deleteCallback;
|
528
|
+
return this;
|
529
|
+
}
|
530
|
+
setPhantomCursor(peh) {
|
531
|
+
this.phantomElementHandler = peh;
|
532
|
+
return this;
|
533
|
+
}
|
534
|
+
}
|
535
|
+
exports.default = ClickModeHandler;
|
@@ -2,22 +2,25 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
const d3 = require("d3");
|
4
4
|
const random_1 = require("../utils/random");
|
5
|
-
const
|
6
|
-
|
7
|
-
|
5
|
+
const coordinates = require("../utils/coordinates");
|
6
|
+
const cq = require("../utils/convenienceQueries");
|
7
|
+
class CustomAnnotationShapeDrawer {
|
8
|
+
constructor(containerId) {
|
9
|
+
this.setContainerId(containerId);
|
8
10
|
this.shapes = new Array();
|
9
11
|
this.shapeID = "";
|
10
12
|
this.dragged = false;
|
11
|
-
this.canvas = d3.select(
|
13
|
+
this.canvas = d3.select("#" + this.containerId + " #interactionOverlay"); // draw directly in svg
|
12
14
|
this.dragBehaviour = d3.drag()
|
13
15
|
.on('start', drawStart)
|
14
16
|
.on('drag', this.drawing.bind(this))
|
15
17
|
.on('end', this.drawEnd.bind(this));
|
16
18
|
var that = this;
|
17
19
|
function drawStart() {
|
18
|
-
|
19
|
-
that.
|
20
|
-
|
20
|
+
var pt = coordinates.transformToDOMMatrixCoordinates(d3.event.sourceEvent.clientX, d3.event.sourceEvent.clientY, that.interactionOverlay);
|
21
|
+
that.initialX = pt.x; //d3.event.x
|
22
|
+
that.initialY = pt.y; //d3.event.y
|
23
|
+
if (d3.event.sourceEvent.srcElement.id === that.interactionOverlay.id) {
|
21
24
|
that.initRect(that.initialX, that.initialY);
|
22
25
|
//that.initCircle(that.initialX, that.initialY)
|
23
26
|
}
|
@@ -25,10 +28,10 @@ class CustomAnnotationDrawer {
|
|
25
28
|
this.setListeners();
|
26
29
|
}
|
27
30
|
drawing() {
|
28
|
-
|
29
|
-
const curX = d3.event.x
|
30
|
-
const curY = d3.event.y
|
31
|
-
if (
|
31
|
+
var pt = coordinates.transformToDOMMatrixCoordinates(d3.event.sourceEvent.clientX, d3.event.sourceEvent.clientY, this.interactionOverlay);
|
32
|
+
const curX = pt.x; //d3.event.x
|
33
|
+
const curY = pt.y; //d3.event.y
|
34
|
+
if (this.shape == undefined) {
|
32
35
|
return;
|
33
36
|
}
|
34
37
|
if (Math.abs(curX - this.initialX) > 20 || Math.abs(curY - this.initialY) > 20) {
|
@@ -42,14 +45,22 @@ class CustomAnnotationDrawer {
|
|
42
45
|
}
|
43
46
|
}
|
44
47
|
drawEnd() {
|
48
|
+
if (this.shapeID === "")
|
49
|
+
return;
|
45
50
|
if (!this.dragged) {
|
46
|
-
var elToRemove =
|
51
|
+
var elToRemove = this.interactionOverlay.querySelector("#" + this.shapeID);
|
47
52
|
if (elToRemove !== null) {
|
48
53
|
elToRemove.remove();
|
49
54
|
}
|
50
55
|
}
|
51
56
|
else {
|
52
|
-
|
57
|
+
var annotCanvas = this.interactionOverlay.querySelector("#annotationCanvas");
|
58
|
+
var pt = coordinates.getDOMMatrixCoordinates(this.shape, annotCanvas);
|
59
|
+
this.interactionOverlay.querySelector("#annotationCanvas").appendChild(this.shape);
|
60
|
+
this.shape.setAttribute("x", pt.left.toString());
|
61
|
+
this.shape.setAttribute("y", pt.top.toString());
|
62
|
+
this.shape.setAttribute("width", pt.width.toString());
|
63
|
+
this.shape.setAttribute("height", pt.height.toString());
|
53
64
|
this.shapes.push(this.shape.cloneNode(true));
|
54
65
|
}
|
55
66
|
this.shape = undefined;
|
@@ -90,7 +101,7 @@ class CustomAnnotationDrawer {
|
|
90
101
|
this.shape.setAttribute('ry', currentHeight.toString());
|
91
102
|
}
|
92
103
|
removeListeners() {
|
93
|
-
d3.select(
|
104
|
+
d3.select("#" + this.containerId + " #interactionOverlay").on('mousedown.drag', null);
|
94
105
|
}
|
95
106
|
setListeners() {
|
96
107
|
this.canvas.call(this.dragBehaviour);
|
@@ -100,8 +111,14 @@ class CustomAnnotationDrawer {
|
|
100
111
|
this.setListeners();
|
101
112
|
}
|
102
113
|
///////// GETTER/ SETTER ////////
|
103
|
-
|
104
|
-
this.
|
114
|
+
setm2s(m2s) {
|
115
|
+
this.m2s = m2s;
|
116
|
+
}
|
117
|
+
setContainerId(id) {
|
118
|
+
this.containerId = id;
|
119
|
+
this.container = document.getElementById(id);
|
120
|
+
this.interactionOverlay = cq.getInteractOverlay(id);
|
121
|
+
this.vrvSVG = cq.getVrvSVG(id);
|
105
122
|
}
|
106
123
|
getShapes() {
|
107
124
|
return this.shapes;
|
@@ -111,4 +128,4 @@ class CustomAnnotationDrawer {
|
|
111
128
|
this.updateCallback = updateCallback;
|
112
129
|
}
|
113
130
|
}
|
114
|
-
exports.default =
|
131
|
+
exports.default = CustomAnnotationShapeDrawer;
|