solid-pianoroll 0.0.14 → 0.0.15
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/dist/cjs/index.js +371 -418
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +374 -420
- package/dist/esm/index.js.map +1 -1
- package/dist/source/PianoRoll.jsx +18 -3
- package/dist/source/PianoRollContext.jsx +5 -2
- package/dist/source/PianoRollGrid.jsx +20 -3
- package/dist/source/PianoRollNotes.jsx +117 -81
- package/dist/source/PianoRollTrackList.jsx +28 -0
- package/dist/source/index.jsx +1 -2
- package/dist/source/usePianoRoll.js +4 -4
- package/dist/types/PianoRoll.d.ts +10 -6
- package/dist/types/PianoRollContext.d.ts +1 -1
- package/dist/types/PianoRollTrackList.d.ts +2 -0
- package/dist/types/index.d.ts +1 -2
- package/dist/types/usePianoRoll.d.ts +2 -2
- package/package.json +1 -1
- package/dist/source/MultiTrackPianoRoll.jsx +0 -156
- package/dist/types/MultiTrackPianoRoll.d.ts +0 -13
package/dist/cjs/index.js
CHANGED
|
@@ -29,9 +29,9 @@ function styleInject(css, ref) {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
var css_248z$
|
|
33
|
-
var styles$
|
|
34
|
-
styleInject(css_248z$
|
|
32
|
+
var css_248z$4 = ".PianoRoll-module_PianoRoll__rkRYx {\n box-sizing: border-box;\n display: flex;\n overflow: hidden;\n flex-direction: column;\n}\n\n.PianoRoll-module_PianoRollContainer__Oyxr7 {\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: row;\n}\n";
|
|
33
|
+
var styles$4 = {"PianoRoll":"PianoRoll-module_PianoRoll__rkRYx","PianoRollContainer":"PianoRoll-module_PianoRollContainer__Oyxr7"};
|
|
34
|
+
styleInject(css_248z$4);
|
|
35
35
|
|
|
36
36
|
const PianoRollContext = solidJs.createContext();
|
|
37
37
|
const PianoRollContextProvider = PianoRollContext.Provider;
|
|
@@ -40,30 +40,11 @@ const usePianoRollContext = () => {
|
|
|
40
40
|
if (!context) throw new Error("No PianoRollContext found");
|
|
41
41
|
return context;
|
|
42
42
|
};
|
|
43
|
-
const splitContextProps = allProps => solidJs.splitProps(allProps, ["
|
|
43
|
+
const splitContextProps = allProps => solidJs.splitProps(allProps, ["mode", "duration", "gridDivision", "tracks", "position", "ppq", "snapToGrid", "verticalPosition", "verticalZoom", "zoom", "onInsertNote", "onNoteChange", "onPositionChange", "onRemoveNote", "onVerticalPositionChange", "onVerticalZoomChange", "onZoomChange", "showAllTracks", "selectedTrackIndex", "onSelectedTrackIndexChange"]);
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return (() => {
|
|
49
|
-
const _el$ = _tmpl$$8.cloneNode(true);
|
|
50
|
-
web.spread(_el$, web.mergeProps(props, {
|
|
51
|
-
get value() {
|
|
52
|
-
return context.zoom;
|
|
53
|
-
},
|
|
54
|
-
"onInput": event => context.onZoomChange?.(event.currentTarget.valueAsNumber),
|
|
55
|
-
"type": "range",
|
|
56
|
-
get style() {
|
|
57
|
-
return {
|
|
58
|
-
"margin-left": "50px",
|
|
59
|
-
"margin-right": "16px",
|
|
60
|
-
...(typeof props.style === "object" && props.style)
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}), false, false);
|
|
64
|
-
return _el$;
|
|
65
|
-
})();
|
|
66
|
-
};
|
|
45
|
+
var css_248z$3 = ".PianoRollKeys-module_PianoRollKeys__5vnQ0 {\n position: relative;\n height: 100%;\n width: 50px;\n}\n\n.PianoRollKeys-module_Key__jybNC {\n border-width: 0px;\n position: absolute;\n box-sizing: border-box;\n width: 100%;\n border-color: #000;\n border-style: solid;\n border-right-width: 1px;\n}\n\n.PianoRollKeys-module_black__7rncB {\n background: black;\n}\n\n.PianoRollKeys-module_white__fR2Lm {\n background: white;\n}\n\n.PianoRollKeys-module_whiteAndNextIsWhite__PN1O8 {\n border-top-width: 0.1px;\n}\n\n.PianoRollKeys-module_whiteAndPreviousIsWhite__-fP3q {\n border-bottom-width: 0.1px;\n}\n";
|
|
46
|
+
var styles$3 = {"PianoRollKeys":"PianoRollKeys-module_PianoRollKeys__5vnQ0","Key":"PianoRollKeys-module_Key__jybNC","black":"PianoRollKeys-module_black__7rncB","white":"PianoRollKeys-module_white__fR2Lm","whiteAndNextIsWhite":"PianoRollKeys-module_whiteAndNextIsWhite__PN1O8","whiteAndPreviousIsWhite":"PianoRollKeys-module_whiteAndPreviousIsWhite__-fP3q"};
|
|
47
|
+
styleInject(css_248z$3);
|
|
67
48
|
|
|
68
49
|
function createViewPortDimension(getState) {
|
|
69
50
|
const getStateWithFunctions = () => ({
|
|
@@ -137,6 +118,65 @@ const useViewPortDimension = name => {
|
|
|
137
118
|
return viewPort;
|
|
138
119
|
};
|
|
139
120
|
|
|
121
|
+
const _tmpl$$8 = /*#__PURE__*/web.template(`<div></div>`, 2);
|
|
122
|
+
const PianoRollKeys = () => {
|
|
123
|
+
const viewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
|
|
124
|
+
return (() => {
|
|
125
|
+
const _el$ = _tmpl$$8.cloneNode(true);
|
|
126
|
+
web.insert(_el$, web.createComponent(solidJs.Index, {
|
|
127
|
+
each: keys,
|
|
128
|
+
children: key => {
|
|
129
|
+
const virtualDimensions = solidJs.createMemo(() => viewPort().calculatePixelDimensions(127 - key().number, 1));
|
|
130
|
+
return web.createComponent(solidJs.Show, {
|
|
131
|
+
get when() {
|
|
132
|
+
return virtualDimensions().size > 0;
|
|
133
|
+
},
|
|
134
|
+
get children() {
|
|
135
|
+
const _el$2 = _tmpl$$8.cloneNode(true);
|
|
136
|
+
web.effect(_p$ => {
|
|
137
|
+
const _v$ = {
|
|
138
|
+
[styles$3["Key"]]: true,
|
|
139
|
+
[styles$3["black"]]: key().isBlack,
|
|
140
|
+
[styles$3["white"]]: !key().isBlack,
|
|
141
|
+
[styles$3["whiteAndNextIsWhite"]]: !key().isBlack && !blackKeys.includes((key().number + 1) % 12),
|
|
142
|
+
[styles$3["whiteAndPreviousIsWhite"]]: !key().isBlack && !blackKeys.includes((key().number - 1) % 12)
|
|
143
|
+
},
|
|
144
|
+
_v$2 = key().name,
|
|
145
|
+
_v$3 = key().number % 12,
|
|
146
|
+
_v$4 = `${virtualDimensions().offset}px`,
|
|
147
|
+
_v$5 = `${virtualDimensions().size}px`;
|
|
148
|
+
_p$._v$ = web.classList(_el$2, _v$, _p$._v$);
|
|
149
|
+
_v$2 !== _p$._v$2 && web.setAttribute(_el$2, "title", _p$._v$2 = _v$2);
|
|
150
|
+
_v$3 !== _p$._v$3 && web.setAttribute(_el$2, "data-index", _p$._v$3 = _v$3);
|
|
151
|
+
_v$4 !== _p$._v$4 && _el$2.style.setProperty("top", _p$._v$4 = _v$4);
|
|
152
|
+
_v$5 !== _p$._v$5 && _el$2.style.setProperty("height", _p$._v$5 = _v$5);
|
|
153
|
+
return _p$;
|
|
154
|
+
}, {
|
|
155
|
+
_v$: undefined,
|
|
156
|
+
_v$2: undefined,
|
|
157
|
+
_v$3: undefined,
|
|
158
|
+
_v$4: undefined,
|
|
159
|
+
_v$5: undefined
|
|
160
|
+
});
|
|
161
|
+
return _el$2;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}));
|
|
166
|
+
web.effect(() => web.className(_el$, styles$3.PianoRollKeys));
|
|
167
|
+
return _el$;
|
|
168
|
+
})();
|
|
169
|
+
};
|
|
170
|
+
const blackKeys = [1, 3, 6, 8, 10];
|
|
171
|
+
const keyNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
172
|
+
const keys = Array.from({
|
|
173
|
+
length: 128
|
|
174
|
+
}).map((_, index) => ({
|
|
175
|
+
number: index,
|
|
176
|
+
name: `${keyNames[index % 12]} ${Math.floor(index / 12) - 2}`,
|
|
177
|
+
isBlack: blackKeys.includes(index % 12)
|
|
178
|
+
}));
|
|
179
|
+
|
|
140
180
|
var css_248z$2 = ".PianoRollNotes-module_PianoRollNotes__6pF-y {\n position: absolute;\n flex: 1;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 1;\n cursor: grab;\n}\n.PianoRollNotes-module_PianoRollNotes__6pF-y .PianoRollNotes-module_Note__-jxLb {\n position: absolute;\n box-sizing: border-box;\n border-width: 0.5px;\n border-style: solid;\n border-color: #a00;\n cursor: move;\n}\n.PianoRollNotes-module_PianoRollNotes__6pF-y .PianoRollNotes-module_Note__-jxLb.PianoRollNotes-module_trimStart__vuBlj {\n cursor: w-resize;\n}\n.PianoRollNotes-module_PianoRollNotes__6pF-y .PianoRollNotes-module_Note__-jxLb.PianoRollNotes-module_trimEnd__zPdjr {\n cursor: e-resize;\n}";
|
|
141
181
|
var styles$2 = {"PianoRollNotes":"PianoRollNotes-module_PianoRollNotes__6pF-y","Note":"PianoRollNotes-module_Note__-jxLb","trimStart":"PianoRollNotes-module_trimStart__vuBlj","trimEnd":"PianoRollNotes-module_trimEnd__zPdjr"};
|
|
142
182
|
styleInject(css_248z$2);
|
|
@@ -150,10 +190,11 @@ const PianoRollNotes = props => {
|
|
|
150
190
|
const snapValueToGridIfEnabled = (value, altKey) => context.snapToGrid && !altKey ? Math.round(value / gridDivisionTicks()) * gridDivisionTicks() : value;
|
|
151
191
|
const insertOrUpdateNote = event => {
|
|
152
192
|
const position = horizontalViewPort().calculatePosition(event.clientX);
|
|
153
|
-
const
|
|
193
|
+
const existingNote = currentNote();
|
|
194
|
+
const midi = context.mode === "keys" ? 127 - Math.floor(verticalViewPort().calculatePosition(event.clientY)) : existingNote?.midi ?? 60;
|
|
195
|
+
const targetTrackIndex = context.mode === "tracks" ? Math.floor(verticalViewPort().calculatePosition(event.clientY)) : context.selectedTrackIndex ?? 0;
|
|
154
196
|
const eventPositionTicks = Math.floor(position / gridDivisionTicks()) * gridDivisionTicks();
|
|
155
197
|
const velocity = 127;
|
|
156
|
-
const existingNote = newNote();
|
|
157
198
|
const ticks = existingNote?.ticks ?? eventPositionTicks;
|
|
158
199
|
const durationTicks = existingNote?.ticks ? eventPositionTicks - existingNote?.ticks : gridDivisionTicks();
|
|
159
200
|
const note = {
|
|
@@ -163,25 +204,26 @@ const PianoRollNotes = props => {
|
|
|
163
204
|
velocity
|
|
164
205
|
};
|
|
165
206
|
if (existingNote) {
|
|
166
|
-
context.onNoteChange?.(
|
|
167
|
-
return
|
|
207
|
+
context.onNoteChange?.(currentNoteTrackIndex(), currentNoteIndex(), note);
|
|
208
|
+
return currentNoteIndex();
|
|
168
209
|
} else {
|
|
169
|
-
return context.onInsertNote?.(note) ?? -1;
|
|
210
|
+
return context.onInsertNote?.(targetTrackIndex, note) ?? -1;
|
|
170
211
|
}
|
|
171
212
|
};
|
|
172
213
|
const [isDragging, setIsDragging] = solidJs.createSignal(false);
|
|
173
214
|
const [noteDragMode, setNoteDragMode] = solidJs.createSignal();
|
|
174
|
-
const [
|
|
215
|
+
const [currentNoteIndex, setCurrentNoteIndex] = solidJs.createSignal(-1);
|
|
216
|
+
const [currentNoteTrackIndex, setCurrentNoteTrackIndex] = solidJs.createSignal(-1);
|
|
175
217
|
const [isMouseDown, setIsMouseDown] = solidJs.createSignal(false);
|
|
176
|
-
const
|
|
218
|
+
const currentNote = solidJs.createMemo(() => context.tracks[currentNoteTrackIndex()]?.notes[currentNoteIndex()]);
|
|
177
219
|
const getClasses = noteDragMode => {
|
|
178
220
|
return noteDragMode ? [styles$2.Note, styles$2[noteDragMode]] : [styles$2.Note];
|
|
179
221
|
};
|
|
180
222
|
return (() => {
|
|
181
223
|
const _el$ = _tmpl$$7.cloneNode(true);
|
|
182
224
|
_el$.$$click = event => {
|
|
183
|
-
if (
|
|
184
|
-
|
|
225
|
+
if (currentNote()) {
|
|
226
|
+
setCurrentNoteIndex(-1);
|
|
185
227
|
return;
|
|
186
228
|
}
|
|
187
229
|
if (!event.altKey) return;
|
|
@@ -202,94 +244,133 @@ const PianoRollNotes = props => {
|
|
|
202
244
|
return;
|
|
203
245
|
}
|
|
204
246
|
const index = insertOrUpdateNote(event);
|
|
205
|
-
|
|
247
|
+
setCurrentNoteIndex(index);
|
|
206
248
|
};
|
|
207
249
|
_el$.$$mousedown = event => {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
250
|
+
solidJs.batch(() => {
|
|
251
|
+
setIsMouseDown(true);
|
|
252
|
+
const index = insertOrUpdateNote(event);
|
|
253
|
+
setCurrentNoteTrackIndex(context.selectedTrackIndex ?? 0);
|
|
254
|
+
setCurrentNoteIndex(index);
|
|
255
|
+
});
|
|
212
256
|
};
|
|
213
257
|
const _ref$ = props.ref;
|
|
214
258
|
typeof _ref$ === "function" ? web.use(_ref$, _el$) : props.ref = _el$;
|
|
215
|
-
web.insert(_el$, web.createComponent(solidJs.
|
|
259
|
+
web.insert(_el$, web.createComponent(solidJs.For, {
|
|
216
260
|
get each() {
|
|
217
|
-
return context.
|
|
261
|
+
return context.tracks;
|
|
218
262
|
},
|
|
219
|
-
children: (
|
|
220
|
-
const verticalVirtualDimensions = solidJs.createMemo(() => verticalViewPort().calculatePixelDimensions(127 - note().midi, 1));
|
|
221
|
-
const horizontalDimensions = solidJs.createMemo(() => horizontalViewPort().calculatePixelDimensions(note().ticks, note().durationTicks));
|
|
263
|
+
children: (track, trackIndex) => {
|
|
222
264
|
return web.createComponent(solidJs.Show, {
|
|
223
265
|
get when() {
|
|
224
|
-
return
|
|
266
|
+
return trackIndex() === context.selectedTrackIndex || context.showAllTracks || context.mode === "tracks";
|
|
225
267
|
},
|
|
226
268
|
get children() {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
269
|
+
return web.createComponent(solidJs.For, {
|
|
270
|
+
get each() {
|
|
271
|
+
return track.notes;
|
|
272
|
+
},
|
|
273
|
+
children: (note, noteIndex) => {
|
|
274
|
+
const verticalVirtualDimensions = solidJs.createMemo(() => verticalViewPort().calculatePixelDimensions(context.mode === "keys" ? 127 - note.midi : trackIndex(), 1));
|
|
275
|
+
const horizontalDimensions = solidJs.createMemo(() => horizontalViewPort().calculatePixelDimensions(note.ticks, note.durationTicks));
|
|
276
|
+
return web.createComponent(solidJs.Show, {
|
|
277
|
+
get when() {
|
|
278
|
+
return web.memo(() => !!verticalViewPort().isVisible(verticalVirtualDimensions()))() && horizontalViewPort().isVisible(horizontalDimensions());
|
|
279
|
+
},
|
|
280
|
+
get children() {
|
|
281
|
+
const _el$2 = _tmpl$$7.cloneNode(true);
|
|
282
|
+
_el$2.$$mousedown = event => {
|
|
283
|
+
event.stopPropagation();
|
|
284
|
+
setIsDragging(true);
|
|
285
|
+
setCurrentNoteIndex(noteIndex());
|
|
286
|
+
setCurrentNoteTrackIndex(trackIndex());
|
|
287
|
+
const initialPosition = horizontalViewPort().calculatePosition(event.clientX);
|
|
288
|
+
const diffPosition = initialPosition - note.ticks;
|
|
289
|
+
const handleMouseMove = mouseMoveEvent => {
|
|
290
|
+
const note = currentNote();
|
|
291
|
+
if (!note) return;
|
|
292
|
+
const ticks = snapValueToGridIfEnabled(Math.max(horizontalViewPort().calculatePosition(mouseMoveEvent.clientX) - diffPosition, 0), mouseMoveEvent.altKey);
|
|
293
|
+
const updatedNote = {
|
|
294
|
+
...note,
|
|
295
|
+
...(noteDragMode() === "move" && context.mode === "keys" && {
|
|
296
|
+
midi: Math.round(127 - verticalViewPort().calculatePosition(mouseMoveEvent.clientY))
|
|
297
|
+
}),
|
|
298
|
+
...((noteDragMode() === "move" || noteDragMode() === "trimStart") && {
|
|
299
|
+
ticks
|
|
300
|
+
}),
|
|
301
|
+
...(noteDragMode() === "trimStart" && {
|
|
302
|
+
durationTicks: note.durationTicks + note.ticks - ticks
|
|
303
|
+
}),
|
|
304
|
+
...(noteDragMode() === "trimEnd" && {
|
|
305
|
+
durationTicks: snapValueToGridIfEnabled(horizontalViewPort().calculatePosition(mouseMoveEvent.clientX) - note.ticks, mouseMoveEvent.altKey)
|
|
306
|
+
})
|
|
307
|
+
};
|
|
308
|
+
const previousTrackIndex = currentNoteTrackIndex();
|
|
309
|
+
const previousNoteIndex = currentNoteIndex();
|
|
310
|
+
const targetTrackIndex = context.mode === "tracks" ? Math.floor(verticalViewPort().calculatePosition(mouseMoveEvent.clientY)) : previousTrackIndex;
|
|
311
|
+
if (targetTrackIndex === previousTrackIndex) {
|
|
312
|
+
context.onNoteChange?.(previousTrackIndex, previousNoteIndex, updatedNote);
|
|
313
|
+
} else {
|
|
314
|
+
solidJs.batch(() => {
|
|
315
|
+
if (context.onInsertNote) {
|
|
316
|
+
context.onRemoveNote?.(previousTrackIndex, previousNoteIndex);
|
|
317
|
+
const newNoteIndex = context.onInsertNote(targetTrackIndex, updatedNote);
|
|
318
|
+
setCurrentNoteTrackIndex(targetTrackIndex);
|
|
319
|
+
setCurrentNoteIndex(newNoteIndex);
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
const handleMouseUp = () => {
|
|
325
|
+
setIsDragging(false);
|
|
326
|
+
setCurrentNoteIndex(-1);
|
|
327
|
+
setCurrentNoteTrackIndex(-1);
|
|
328
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
329
|
+
window.removeEventListener("mouseup", handleMouseUp);
|
|
330
|
+
};
|
|
331
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
332
|
+
window.addEventListener("mouseup", handleMouseUp);
|
|
333
|
+
};
|
|
334
|
+
_el$2.$$dblclick = event => {
|
|
335
|
+
event.stopPropagation();
|
|
336
|
+
context.onRemoveNote?.(trackIndex(), noteIndex());
|
|
337
|
+
};
|
|
338
|
+
_el$2.$$mousemove = event => {
|
|
339
|
+
if (isDragging()) return;
|
|
340
|
+
event.stopPropagation();
|
|
341
|
+
const relativeX = horizontalViewPort().calculatePixelValue(horizontalViewPort().calculatePosition(event.clientX));
|
|
342
|
+
const noteStartX = horizontalViewPort().calculatePixelValue(note.ticks);
|
|
343
|
+
const noteEndX = horizontalViewPort().calculatePixelValue(note.ticks + note.durationTicks);
|
|
344
|
+
setNoteDragMode(relativeX - noteStartX < 3 ? "trimStart" : noteEndX - relativeX < 3 ? "trimEnd" : "move");
|
|
345
|
+
};
|
|
346
|
+
web.setAttribute(_el$2, "draggable", false);
|
|
347
|
+
web.effect(_p$ => {
|
|
348
|
+
const _v$ = getClasses(noteDragMode()).join(" "),
|
|
349
|
+
_v$2 = `rgba(255,0,0, ${(128 + note.velocity) / 256})`,
|
|
350
|
+
_v$3 = `${verticalVirtualDimensions().offset}px`,
|
|
351
|
+
_v$4 = `${verticalVirtualDimensions().size}px`,
|
|
352
|
+
_v$5 = `${horizontalDimensions().offset}px`,
|
|
353
|
+
_v$6 = `${horizontalDimensions().size}px`;
|
|
354
|
+
_v$ !== _p$._v$ && web.className(_el$2, _p$._v$ = _v$);
|
|
355
|
+
_v$2 !== _p$._v$2 && _el$2.style.setProperty("background-color", _p$._v$2 = _v$2);
|
|
356
|
+
_v$3 !== _p$._v$3 && _el$2.style.setProperty("top", _p$._v$3 = _v$3);
|
|
357
|
+
_v$4 !== _p$._v$4 && _el$2.style.setProperty("height", _p$._v$4 = _v$4);
|
|
358
|
+
_v$5 !== _p$._v$5 && _el$2.style.setProperty("left", _p$._v$5 = _v$5);
|
|
359
|
+
_v$6 !== _p$._v$6 && _el$2.style.setProperty("width", _p$._v$6 = _v$6);
|
|
360
|
+
return _p$;
|
|
361
|
+
}, {
|
|
362
|
+
_v$: undefined,
|
|
363
|
+
_v$2: undefined,
|
|
364
|
+
_v$3: undefined,
|
|
365
|
+
_v$4: undefined,
|
|
366
|
+
_v$5: undefined,
|
|
367
|
+
_v$6: undefined
|
|
368
|
+
});
|
|
369
|
+
return _el$2;
|
|
370
|
+
}
|
|
249
371
|
});
|
|
250
|
-
}
|
|
251
|
-
const handleMouseUp = () => {
|
|
252
|
-
setIsDragging(false);
|
|
253
|
-
window.removeEventListener("mousemove", handleMouseMove);
|
|
254
|
-
window.removeEventListener("mouseup", handleMouseUp);
|
|
255
|
-
};
|
|
256
|
-
window.addEventListener("mousemove", handleMouseMove);
|
|
257
|
-
window.addEventListener("mouseup", handleMouseUp);
|
|
258
|
-
};
|
|
259
|
-
_el$2.$$dblclick = event => {
|
|
260
|
-
event.stopPropagation();
|
|
261
|
-
context.onRemoveNote?.(index);
|
|
262
|
-
};
|
|
263
|
-
_el$2.$$mousemove = event => {
|
|
264
|
-
if (isDragging()) return;
|
|
265
|
-
event.stopPropagation();
|
|
266
|
-
const relativeX = horizontalViewPort().calculatePixelValue(horizontalViewPort().calculatePosition(event.clientX));
|
|
267
|
-
const noteStartX = horizontalViewPort().calculatePixelValue(note().ticks);
|
|
268
|
-
const noteEndX = horizontalViewPort().calculatePixelValue(note().ticks + note().durationTicks);
|
|
269
|
-
setNoteDragMode(relativeX - noteStartX < 3 ? "trimStart" : noteEndX - relativeX < 3 ? "trimEnd" : "move");
|
|
270
|
-
};
|
|
271
|
-
web.effect(_p$ => {
|
|
272
|
-
const _v$ = getClasses(noteDragMode()).join(" "),
|
|
273
|
-
_v$2 = {
|
|
274
|
-
"background-color": `rgba(255,0,0, ${(128 + note().velocity) / 256})`,
|
|
275
|
-
...(context.condensed ? {
|
|
276
|
-
top: 0,
|
|
277
|
-
height: "100%"
|
|
278
|
-
} : {
|
|
279
|
-
top: `${verticalVirtualDimensions().offset}px`,
|
|
280
|
-
height: `${verticalVirtualDimensions().size}px`
|
|
281
|
-
}),
|
|
282
|
-
left: `${horizontalDimensions().offset}px`,
|
|
283
|
-
width: `${horizontalDimensions().size}px`
|
|
284
|
-
};
|
|
285
|
-
_v$ !== _p$._v$ && web.className(_el$2, _p$._v$ = _v$);
|
|
286
|
-
_p$._v$2 = web.style(_el$2, _v$2, _p$._v$2);
|
|
287
|
-
return _p$;
|
|
288
|
-
}, {
|
|
289
|
-
_v$: undefined,
|
|
290
|
-
_v$2: undefined
|
|
372
|
+
}
|
|
291
373
|
});
|
|
292
|
-
return _el$2;
|
|
293
374
|
}
|
|
294
375
|
});
|
|
295
376
|
}
|
|
@@ -403,74 +484,11 @@ const ScrollContainer = props => {
|
|
|
403
484
|
})();
|
|
404
485
|
};
|
|
405
486
|
|
|
406
|
-
var css_248z$1 = ".
|
|
407
|
-
var styles$1 = {"
|
|
487
|
+
var css_248z$1 = ".PianoRollGrid-module_PianoRollGrid__tG119 {\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.PianoRollGrid-module_PianoRollGrid-Row__nRMCs {\n position: absolute;\n border-style: solid;\n border-color: gray;\n}\n\n.PianoRollGrid-module_PianoRollGrid-Time__jLz3E {\n position: absolute;\n box-sizing: border-box;\n top: 0px;\n height: 100%;\n border-left-style: solid;\n border-left-width: 0.5px;\n}\n";
|
|
488
|
+
var styles$1 = {"PianoRollGrid":"PianoRollGrid-module_PianoRollGrid__tG119","PianoRollGrid-Row":"PianoRollGrid-module_PianoRollGrid-Row__nRMCs","PianoRollGrid-Time":"PianoRollGrid-module_PianoRollGrid-Time__jLz3E"};
|
|
408
489
|
styleInject(css_248z$1);
|
|
409
490
|
|
|
410
491
|
const _tmpl$$5 = /*#__PURE__*/web.template(`<div></div>`, 2);
|
|
411
|
-
const PianoRollKeys = () => {
|
|
412
|
-
const viewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
|
|
413
|
-
return (() => {
|
|
414
|
-
const _el$ = _tmpl$$5.cloneNode(true);
|
|
415
|
-
web.insert(_el$, web.createComponent(solidJs.Index, {
|
|
416
|
-
each: keys,
|
|
417
|
-
children: key => {
|
|
418
|
-
const virtualDimensions = solidJs.createMemo(() => viewPort().calculatePixelDimensions(127 - key().number, 1));
|
|
419
|
-
return web.createComponent(solidJs.Show, {
|
|
420
|
-
get when() {
|
|
421
|
-
return virtualDimensions().size > 0;
|
|
422
|
-
},
|
|
423
|
-
get children() {
|
|
424
|
-
const _el$2 = _tmpl$$5.cloneNode(true);
|
|
425
|
-
web.effect(_p$ => {
|
|
426
|
-
const _v$ = {
|
|
427
|
-
[styles$1["Key"]]: true,
|
|
428
|
-
[styles$1["black"]]: key().isBlack,
|
|
429
|
-
[styles$1["white"]]: !key().isBlack,
|
|
430
|
-
[styles$1["whiteAndNextIsWhite"]]: !key().isBlack && !blackKeys.includes((key().number + 1) % 12),
|
|
431
|
-
[styles$1["whiteAndPreviousIsWhite"]]: !key().isBlack && !blackKeys.includes((key().number - 1) % 12)
|
|
432
|
-
},
|
|
433
|
-
_v$2 = key().name,
|
|
434
|
-
_v$3 = key().number % 12,
|
|
435
|
-
_v$4 = `${virtualDimensions().offset}px`,
|
|
436
|
-
_v$5 = `${virtualDimensions().size}px`;
|
|
437
|
-
_p$._v$ = web.classList(_el$2, _v$, _p$._v$);
|
|
438
|
-
_v$2 !== _p$._v$2 && web.setAttribute(_el$2, "title", _p$._v$2 = _v$2);
|
|
439
|
-
_v$3 !== _p$._v$3 && web.setAttribute(_el$2, "data-index", _p$._v$3 = _v$3);
|
|
440
|
-
_v$4 !== _p$._v$4 && _el$2.style.setProperty("top", _p$._v$4 = _v$4);
|
|
441
|
-
_v$5 !== _p$._v$5 && _el$2.style.setProperty("height", _p$._v$5 = _v$5);
|
|
442
|
-
return _p$;
|
|
443
|
-
}, {
|
|
444
|
-
_v$: undefined,
|
|
445
|
-
_v$2: undefined,
|
|
446
|
-
_v$3: undefined,
|
|
447
|
-
_v$4: undefined,
|
|
448
|
-
_v$5: undefined
|
|
449
|
-
});
|
|
450
|
-
return _el$2;
|
|
451
|
-
}
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
}));
|
|
455
|
-
web.effect(() => web.className(_el$, styles$1.PianoRollKeys));
|
|
456
|
-
return _el$;
|
|
457
|
-
})();
|
|
458
|
-
};
|
|
459
|
-
const blackKeys = [1, 3, 6, 8, 10];
|
|
460
|
-
const keyNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
461
|
-
const keys = Array.from({
|
|
462
|
-
length: 128
|
|
463
|
-
}).map((_, index) => ({
|
|
464
|
-
number: index,
|
|
465
|
-
name: `${keyNames[index % 12]} ${Math.floor(index / 12) - 2}`,
|
|
466
|
-
isBlack: blackKeys.includes(index % 12)
|
|
467
|
-
}));
|
|
468
|
-
|
|
469
|
-
var css_248z = ".PianoRollGrid-module_PianoRollGrid__tG119 {\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.PianoRollGrid-module_PianoRollGrid-Key__VRbiB {\n position: absolute;\n border-style: solid;\n border-color: gray;\n}\n\n.PianoRollGrid-module_PianoRollGrid-Time__jLz3E {\n position: absolute;\n box-sizing: border-box;\n top: 0px;\n height: 100%;\n border-left-style: solid;\n border-left-width: 0.5px;\n}\n";
|
|
470
|
-
var styles = {"PianoRollGrid":"PianoRollGrid-module_PianoRollGrid__tG119","PianoRollGrid-Key":"PianoRollGrid-module_PianoRollGrid-Key__VRbiB","PianoRollGrid-Time":"PianoRollGrid-module_PianoRollGrid-Time__jLz3E"};
|
|
471
|
-
styleInject(css_248z);
|
|
472
|
-
|
|
473
|
-
const _tmpl$$4 = /*#__PURE__*/web.template(`<div></div>`, 2);
|
|
474
492
|
const PianoRollGrid = () => {
|
|
475
493
|
const context = usePianoRollContext();
|
|
476
494
|
const verticalViewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
|
|
@@ -500,7 +518,7 @@ const PianoRollGrid = () => {
|
|
|
500
518
|
}));
|
|
501
519
|
});
|
|
502
520
|
return (() => {
|
|
503
|
-
const _el$ = _tmpl$$
|
|
521
|
+
const _el$ = _tmpl$$5.cloneNode(true);
|
|
504
522
|
web.insert(_el$, web.createComponent(solidJs.Index, {
|
|
505
523
|
get each() {
|
|
506
524
|
return gridArray();
|
|
@@ -512,9 +530,9 @@ const PianoRollGrid = () => {
|
|
|
512
530
|
return virtualDimensions().size > 0;
|
|
513
531
|
},
|
|
514
532
|
get children() {
|
|
515
|
-
const _el$2 = _tmpl$$
|
|
533
|
+
const _el$2 = _tmpl$$5.cloneNode(true);
|
|
516
534
|
web.effect(_p$ => {
|
|
517
|
-
const _v$ = styles["PianoRollGrid-Time"],
|
|
535
|
+
const _v$ = styles$1["PianoRollGrid-Time"],
|
|
518
536
|
_v$2 = Math.ceil((entry().index + 1 * selectedGridDivisorTicks()) / measureTicks()) % 2 === 0 ? "#ddd" : "#ccc",
|
|
519
537
|
_v$3 = `${virtualDimensions().offset}px`,
|
|
520
538
|
_v$4 = `${virtualDimensions().size}px`,
|
|
@@ -539,7 +557,7 @@ const PianoRollGrid = () => {
|
|
|
539
557
|
}), null);
|
|
540
558
|
web.insert(_el$, web.createComponent(solidJs.Show, {
|
|
541
559
|
get when() {
|
|
542
|
-
return
|
|
560
|
+
return context.mode === "keys";
|
|
543
561
|
},
|
|
544
562
|
get children() {
|
|
545
563
|
return web.createComponent(solidJs.Index, {
|
|
@@ -551,10 +569,10 @@ const PianoRollGrid = () => {
|
|
|
551
569
|
return virtualDimensions().size > 0;
|
|
552
570
|
},
|
|
553
571
|
get children() {
|
|
554
|
-
const _el$3 = _tmpl$$
|
|
572
|
+
const _el$3 = _tmpl$$5.cloneNode(true);
|
|
555
573
|
_el$3.style.setProperty("width", "100%");
|
|
556
574
|
web.effect(_p$ => {
|
|
557
|
-
const _v$6 = styles["PianoRollGrid-
|
|
575
|
+
const _v$6 = styles$1["PianoRollGrid-Row"],
|
|
558
576
|
_v$7 = `${virtualDimensions().offset}px`,
|
|
559
577
|
_v$8 = `${virtualDimensions().size}px`,
|
|
560
578
|
_v$9 = key().isBlack ? "rgba(0,0,0,0.2)" : "none",
|
|
@@ -579,35 +597,53 @@ const PianoRollGrid = () => {
|
|
|
579
597
|
});
|
|
580
598
|
}
|
|
581
599
|
}), null);
|
|
582
|
-
web.
|
|
600
|
+
web.insert(_el$, web.createComponent(solidJs.Show, {
|
|
601
|
+
get when() {
|
|
602
|
+
return context.mode === "tracks";
|
|
603
|
+
},
|
|
604
|
+
get children() {
|
|
605
|
+
return web.createComponent(solidJs.For, {
|
|
606
|
+
get each() {
|
|
607
|
+
return context.tracks;
|
|
608
|
+
},
|
|
609
|
+
children: (track, index) => {
|
|
610
|
+
const virtualDimensions = solidJs.createMemo(() => verticalViewPort().calculatePixelDimensions(index(), 1));
|
|
611
|
+
return web.createComponent(solidJs.Show, {
|
|
612
|
+
get when() {
|
|
613
|
+
return virtualDimensions().size > 0;
|
|
614
|
+
},
|
|
615
|
+
get children() {
|
|
616
|
+
const _el$4 = _tmpl$$5.cloneNode(true);
|
|
617
|
+
_el$4.style.setProperty("width", "100%");
|
|
618
|
+
_el$4.style.setProperty("border-width", "0");
|
|
619
|
+
web.effect(_p$ => {
|
|
620
|
+
const _v$11 = styles$1["PianoRollGrid-Row"],
|
|
621
|
+
_v$12 = `${virtualDimensions().offset}px`,
|
|
622
|
+
_v$13 = `${virtualDimensions().size}px`,
|
|
623
|
+
_v$14 = index() % 2 === 0 ? "rgba(0,0,0,0.2)" : "none";
|
|
624
|
+
_v$11 !== _p$._v$11 && web.className(_el$4, _p$._v$11 = _v$11);
|
|
625
|
+
_v$12 !== _p$._v$12 && _el$4.style.setProperty("top", _p$._v$12 = _v$12);
|
|
626
|
+
_v$13 !== _p$._v$13 && _el$4.style.setProperty("height", _p$._v$13 = _v$13);
|
|
627
|
+
_v$14 !== _p$._v$14 && _el$4.style.setProperty("background-color", _p$._v$14 = _v$14);
|
|
628
|
+
return _p$;
|
|
629
|
+
}, {
|
|
630
|
+
_v$11: undefined,
|
|
631
|
+
_v$12: undefined,
|
|
632
|
+
_v$13: undefined,
|
|
633
|
+
_v$14: undefined
|
|
634
|
+
});
|
|
635
|
+
return _el$4;
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
}), null);
|
|
642
|
+
web.effect(() => web.className(_el$, styles$1.PianoRollGrid));
|
|
583
643
|
return _el$;
|
|
584
644
|
})();
|
|
585
645
|
};
|
|
586
646
|
|
|
587
|
-
const useNotes = () => {
|
|
588
|
-
const [notes, onNotesChange] = solidJs.createSignal([]);
|
|
589
|
-
const onNoteChange = (index, note) => {
|
|
590
|
-
onNotesChange([...notes().slice(0, index), note, ...notes().splice(index + 1)]);
|
|
591
|
-
};
|
|
592
|
-
const onInsertNote = note => {
|
|
593
|
-
const index = Math.max(notes().findIndex(({
|
|
594
|
-
ticks
|
|
595
|
-
}) => ticks > note.ticks), 0);
|
|
596
|
-
onNotesChange([...notes().slice(0, index), note, ...notes().splice(index)]);
|
|
597
|
-
return index;
|
|
598
|
-
};
|
|
599
|
-
const onRemoveNote = index => {
|
|
600
|
-
onNotesChange([...notes().slice(0, index), ...notes().splice(index + 1)]);
|
|
601
|
-
};
|
|
602
|
-
return {
|
|
603
|
-
notes,
|
|
604
|
-
onNotesChange,
|
|
605
|
-
onNoteChange,
|
|
606
|
-
onInsertNote,
|
|
607
|
-
onRemoveNote
|
|
608
|
-
};
|
|
609
|
-
};
|
|
610
|
-
|
|
611
647
|
const defaultRect = {
|
|
612
648
|
left: 0,
|
|
613
649
|
width: 0,
|
|
@@ -636,11 +672,11 @@ function useBoundingClientRect(containerRef) {
|
|
|
636
672
|
return boundingClientRect;
|
|
637
673
|
}
|
|
638
674
|
|
|
639
|
-
const _tmpl$$
|
|
675
|
+
const _tmpl$$4 = /*#__PURE__*/web.template(`<input min="1" max="11" step="0.01">`, 1);
|
|
640
676
|
const VerticalZoomControl = props => {
|
|
641
677
|
const context = usePianoRollContext();
|
|
642
678
|
return (() => {
|
|
643
|
-
const _el$ = _tmpl$$
|
|
679
|
+
const _el$ = _tmpl$$4.cloneNode(true);
|
|
644
680
|
web.spread(_el$, web.mergeProps(props, {
|
|
645
681
|
get value() {
|
|
646
682
|
return context.verticalZoom;
|
|
@@ -664,224 +700,91 @@ const VerticalZoomControl = props => {
|
|
|
664
700
|
})();
|
|
665
701
|
};
|
|
666
702
|
|
|
667
|
-
const _tmpl$$
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
_tmpl$4 = /*#__PURE__*/web.template(`<div></div>`, 2),
|
|
671
|
-
_tmpl$5 = /*#__PURE__*/web.template(`<li></li>`, 2);
|
|
672
|
-
const MultiTrackPianoRoll = allProps => {
|
|
673
|
-
const selectedTrack = solidJs.createMemo(() => allProps.tracks[allProps.selectedTrackIndex]);
|
|
674
|
-
const condensed = solidJs.createMemo(() => !selectedTrack());
|
|
675
|
-
const [ownProps, restProps] = solidJs.splitProps(allProps, ["tracks", "selectedTrackIndex"]);
|
|
676
|
-
const [contextProps, divProps] = splitContextProps(solidJs.mergeProps(restProps, {
|
|
677
|
-
notes: [],
|
|
678
|
-
condensed: false,
|
|
679
|
-
onNoteChange: () => undefined,
|
|
680
|
-
onInsertNote: () => -1,
|
|
681
|
-
onRemoveNote: () => undefined
|
|
682
|
-
}));
|
|
683
|
-
const [scrollerRef, setScrollerRef] = solidJs.createSignal();
|
|
684
|
-
const clientRect = useBoundingClientRect(scrollerRef);
|
|
685
|
-
const zoomFactor = 500;
|
|
686
|
-
const minZoom = solidJs.createMemo(() => 1 / (zoomFactor / clientRect().width));
|
|
687
|
-
const maxZoom = solidJs.createMemo(() => 500 * (zoomFactor / clientRect().width));
|
|
688
|
-
const minVerticalZoom = solidJs.createMemo(() => 1 / (zoomFactor / clientRect().height));
|
|
689
|
-
const maxVerticalZoom = solidJs.createMemo(() => 10 * (zoomFactor / clientRect().height));
|
|
703
|
+
const _tmpl$$3 = /*#__PURE__*/web.template(`<input max="500" min="1" step="0.01">`, 1);
|
|
704
|
+
const HorizontalZoomControl = props => {
|
|
705
|
+
const context = usePianoRollContext();
|
|
690
706
|
return (() => {
|
|
691
|
-
const _el$ = _tmpl
|
|
692
|
-
web.spread(_el$, web.mergeProps(
|
|
707
|
+
const _el$ = _tmpl$$3.cloneNode(true);
|
|
708
|
+
web.spread(_el$, web.mergeProps(props, {
|
|
709
|
+
get value() {
|
|
710
|
+
return context.zoom;
|
|
711
|
+
},
|
|
712
|
+
"onInput": event => context.onZoomChange?.(event.currentTarget.valueAsNumber),
|
|
713
|
+
"type": "range",
|
|
693
714
|
get style() {
|
|
694
715
|
return {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
"flex-direction": "row",
|
|
699
|
-
overflow: "hidden",
|
|
700
|
-
...(typeof divProps.style === "object" && divProps.style)
|
|
716
|
+
"margin-left": "50px",
|
|
717
|
+
"margin-right": "16px",
|
|
718
|
+
...(typeof props.style === "object" && props.style)
|
|
701
719
|
};
|
|
702
720
|
}
|
|
703
|
-
}), false,
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
721
|
+
}), false, false);
|
|
722
|
+
return _el$;
|
|
723
|
+
})();
|
|
724
|
+
};
|
|
725
|
+
|
|
726
|
+
var css_248z = ".PianoRollTrackList-module_PianoRollTrackList__pyuxQ {\n position: relative;\n height: 100%;\n flex: 1;\n}\n\n.PianoRollTrackList-module_Track__VZFIg {\n border-width: 0px;\n position: absolute;\n box-sizing: border-box;\n width: 100%;\n border-color: #000;\n border-style: solid;\n border-right-width: 1px;\n border-bottom-width: 1px;\n}\n";
|
|
727
|
+
var styles = {"PianoRollTrackList":"PianoRollTrackList-module_PianoRollTrackList__pyuxQ","Track":"PianoRollTrackList-module_Track__VZFIg"};
|
|
728
|
+
styleInject(css_248z);
|
|
729
|
+
|
|
730
|
+
const _tmpl$$2 = /*#__PURE__*/web.template(`<div></div>`, 2),
|
|
731
|
+
_tmpl$2$1 = /*#__PURE__*/web.template(`<div> </div>`, 2);
|
|
732
|
+
const PianoRollTrackList = () => {
|
|
733
|
+
const viewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
|
|
734
|
+
const context = usePianoRollContext();
|
|
735
|
+
return (() => {
|
|
736
|
+
const _el$ = _tmpl$$2.cloneNode(true);
|
|
737
|
+
web.insert(_el$, web.createComponent(solidJs.Index, {
|
|
738
|
+
get each() {
|
|
739
|
+
return context.tracks;
|
|
709
740
|
},
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
pixelSize: clientRect().width,
|
|
716
|
-
position: contextProps.position,
|
|
717
|
-
range: contextProps.duration,
|
|
718
|
-
zoom: contextProps.zoom * (zoomFactor / clientRect().width),
|
|
719
|
-
onPositionChange: contextProps.onPositionChange,
|
|
720
|
-
onZoomChange: zoom => contextProps.onZoomChange?.(clamp(zoom / (zoomFactor / clientRect().width), minZoom(), maxZoom()))
|
|
721
|
-
}),
|
|
722
|
-
vertical: () => ({
|
|
723
|
-
pixelOffset: clientRect().top,
|
|
724
|
-
pixelSize: clientRect().height,
|
|
725
|
-
position: contextProps.verticalPosition,
|
|
726
|
-
range: 128,
|
|
727
|
-
zoom: contextProps.verticalZoom * (zoomFactor / clientRect().height),
|
|
728
|
-
onPositionChange: contextProps.onVerticalPositionChange,
|
|
729
|
-
onZoomChange: verticalZoom => contextProps.onVerticalZoomChange?.(clamp(verticalZoom / (zoomFactor / clientRect().height), minVerticalZoom(), maxVerticalZoom()))
|
|
730
|
-
})
|
|
741
|
+
children: (track, index) => {
|
|
742
|
+
const virtualDimensions = solidJs.createMemo(() => viewPort().calculatePixelDimensions(context.mode === "tracks" ? index : index * 8, context.mode === "tracks" ? 1 : 8));
|
|
743
|
+
return web.createComponent(solidJs.Show, {
|
|
744
|
+
get when() {
|
|
745
|
+
return virtualDimensions().size > 0;
|
|
731
746
|
},
|
|
732
747
|
get children() {
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
_el$3.style.setProperty("position", "relative");
|
|
743
|
-
web.insert(_el$3, web.createComponent(solidJs.Index, {
|
|
744
|
-
get each() {
|
|
745
|
-
return allProps.tracks;
|
|
746
|
-
},
|
|
747
|
-
children: (track, noteIndex) => (() => {
|
|
748
|
-
const _el$7 = _tmpl$5.cloneNode(true);
|
|
749
|
-
_el$7.$$click = () => {
|
|
750
|
-
if (noteIndex === allProps.selectedTrackIndex) {
|
|
751
|
-
allProps.onSelectedTrackIndexChange(-1);
|
|
752
|
-
} else {
|
|
753
|
-
allProps.onSelectedTrackIndexChange(noteIndex);
|
|
754
|
-
}
|
|
755
|
-
};
|
|
756
|
-
_el$7.style.setProperty("width", "100%");
|
|
757
|
-
_el$7.style.setProperty("height", "30px");
|
|
758
|
-
_el$7.style.setProperty("list-style", "none");
|
|
759
|
-
_el$7.style.setProperty("display", "flex");
|
|
760
|
-
_el$7.style.setProperty("align-items", "center");
|
|
761
|
-
_el$7.style.setProperty("border-top", "1px black solid");
|
|
762
|
-
_el$7.style.setProperty("cursor", "pointer");
|
|
763
|
-
web.insert(_el$7, () => track().name);
|
|
764
|
-
web.effect(() => _el$7.style.setProperty("background", noteIndex === allProps.selectedTrackIndex ? "lightgray" : "none"));
|
|
765
|
-
return _el$7;
|
|
766
|
-
})()
|
|
767
|
-
}));
|
|
768
|
-
web.insert(_el$2, web.createComponent(solidJs.Show, {
|
|
769
|
-
get when() {
|
|
770
|
-
return !condensed();
|
|
771
|
-
},
|
|
772
|
-
get children() {
|
|
773
|
-
return web.createComponent(PianoRollKeys, {});
|
|
774
|
-
}
|
|
775
|
-
}), null);
|
|
776
|
-
return _el$2;
|
|
777
|
-
})(), (() => {
|
|
778
|
-
const _el$4 = _tmpl$3.cloneNode(true),
|
|
779
|
-
_el$5 = _el$4.firstChild;
|
|
780
|
-
_el$4.style.setProperty("flex", "1");
|
|
781
|
-
web.insert(_el$5, web.createComponent(ScrollContainer, {
|
|
782
|
-
ref: setScrollerRef,
|
|
783
|
-
get children() {
|
|
784
|
-
return [web.memo(() => allProps.children), (() => {
|
|
785
|
-
const _el$6 = _tmpl$2.cloneNode(true);
|
|
786
|
-
_el$6.style.setProperty("margin", "0");
|
|
787
|
-
_el$6.style.setProperty("margin-block-start", "0");
|
|
788
|
-
_el$6.style.setProperty("padding-inline-start", "0");
|
|
789
|
-
web.insert(_el$6, web.createComponent(solidJs.Index, {
|
|
790
|
-
get each() {
|
|
791
|
-
return allProps.tracks;
|
|
792
|
-
},
|
|
793
|
-
children: (track, trackIndex) => {
|
|
794
|
-
const notes = useNotes();
|
|
795
|
-
solidJs.createEffect(() => {
|
|
796
|
-
notes.onNotesChange(track().notes);
|
|
797
|
-
});
|
|
798
|
-
const [context, setContext] = store.createStore({
|
|
799
|
-
...contextProps
|
|
800
|
-
});
|
|
801
|
-
solidJs.createEffect(() => {
|
|
802
|
-
setContext({
|
|
803
|
-
...contextProps,
|
|
804
|
-
condensed: condensed(),
|
|
805
|
-
notes: track()?.notes,
|
|
806
|
-
onNoteChange: (noteIndex, note) => allProps?.onNoteChange?.(trackIndex, noteIndex, note),
|
|
807
|
-
onInsertNote: note => allProps.onInsertNote?.(trackIndex, note) ?? -1,
|
|
808
|
-
onRemoveNote: noteIndex => allProps.onRemoveNote?.(trackIndex, noteIndex)
|
|
809
|
-
});
|
|
810
|
-
});
|
|
811
|
-
const verticalViewPort = useViewPortDimension("vertical");
|
|
812
|
-
return web.createComponent(solidJs.Show, {
|
|
813
|
-
get when() {
|
|
814
|
-
return condensed() || allProps.selectedTrackIndex === trackIndex;
|
|
815
|
-
},
|
|
816
|
-
get children() {
|
|
817
|
-
return web.createComponent(PianoRollContextProvider, {
|
|
818
|
-
value: context,
|
|
819
|
-
get children() {
|
|
820
|
-
const _el$8 = _tmpl$5.cloneNode(true);
|
|
821
|
-
_el$8.style.setProperty("display", "flex");
|
|
822
|
-
_el$8.style.setProperty("position", "relative");
|
|
823
|
-
_el$8.style.setProperty("list-style", "none");
|
|
824
|
-
_el$8.style.setProperty("flex-direction", "row");
|
|
825
|
-
_el$8.style.setProperty("border-top", "1px black solid");
|
|
826
|
-
web.insert(_el$8, web.createComponent(PianoRollNotes, {}), null);
|
|
827
|
-
web.insert(_el$8, web.createComponent(PianoRollGrid, {}), null);
|
|
828
|
-
web.effect(() => _el$8.style.setProperty("height", condensed() ? "30px" : `${verticalViewPort.pixelSize}px`));
|
|
829
|
-
return _el$8;
|
|
830
|
-
}
|
|
831
|
-
});
|
|
832
|
-
}
|
|
833
|
-
});
|
|
834
|
-
}
|
|
835
|
-
}));
|
|
836
|
-
return _el$6;
|
|
837
|
-
})()];
|
|
838
|
-
}
|
|
839
|
-
}), null);
|
|
840
|
-
web.insert(_el$5, web.createComponent(solidJs.Show, {
|
|
841
|
-
get when() {
|
|
842
|
-
return !condensed();
|
|
843
|
-
},
|
|
844
|
-
get children() {
|
|
845
|
-
return web.createComponent(VerticalZoomControl, {
|
|
846
|
-
get value() {
|
|
847
|
-
return contextProps.verticalZoom;
|
|
848
|
-
},
|
|
849
|
-
onInput: event => contextProps.onVerticalZoomChange?.(event.currentTarget.valueAsNumber)
|
|
850
|
-
});
|
|
851
|
-
}
|
|
852
|
-
}), null);
|
|
853
|
-
web.insert(_el$4, web.createComponent(HorizontalZoomControl, {
|
|
854
|
-
style: {
|
|
855
|
-
width: "100%",
|
|
856
|
-
"margin-left": 0
|
|
857
|
-
},
|
|
858
|
-
get value() {
|
|
859
|
-
return contextProps.zoom;
|
|
748
|
+
const _el$2 = _tmpl$2$1.cloneNode(true),
|
|
749
|
+
_el$3 = _el$2.firstChild;
|
|
750
|
+
_el$2.$$click = () => context.onSelectedTrackIndexChange?.(index);
|
|
751
|
+
_el$2.style.setProperty("cursor", "pointer");
|
|
752
|
+
web.insert(_el$2, index, _el$3);
|
|
753
|
+
web.insert(_el$2, () => track().name || "[unnamed track]", null);
|
|
754
|
+
web.effect(_p$ => {
|
|
755
|
+
const _v$ = {
|
|
756
|
+
[styles["Track"]]: true
|
|
860
757
|
},
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
758
|
+
_v$2 = track().name,
|
|
759
|
+
_v$3 = `${virtualDimensions().offset}px`,
|
|
760
|
+
_v$4 = `${virtualDimensions().size}px`,
|
|
761
|
+
_v$5 = index === context.selectedTrackIndex ? "gray" : "lightgrey";
|
|
762
|
+
_p$._v$ = web.classList(_el$2, _v$, _p$._v$);
|
|
763
|
+
_v$2 !== _p$._v$2 && web.setAttribute(_el$2, "title", _p$._v$2 = _v$2);
|
|
764
|
+
_v$3 !== _p$._v$3 && _el$2.style.setProperty("top", _p$._v$3 = _v$3);
|
|
765
|
+
_v$4 !== _p$._v$4 && _el$2.style.setProperty("height", _p$._v$4 = _v$4);
|
|
766
|
+
_v$5 !== _p$._v$5 && _el$2.style.setProperty("background", _p$._v$5 = _v$5);
|
|
767
|
+
return _p$;
|
|
768
|
+
}, {
|
|
769
|
+
_v$: undefined,
|
|
770
|
+
_v$2: undefined,
|
|
771
|
+
_v$3: undefined,
|
|
772
|
+
_v$4: undefined,
|
|
773
|
+
_v$5: undefined
|
|
774
|
+
});
|
|
775
|
+
return _el$2;
|
|
875
776
|
}
|
|
876
777
|
});
|
|
877
778
|
}
|
|
878
779
|
}));
|
|
780
|
+
web.effect(() => web.className(_el$, styles.PianoRollTrackList));
|
|
879
781
|
return _el$;
|
|
880
782
|
})();
|
|
881
783
|
};
|
|
882
784
|
web.delegateEvents(["click"]);
|
|
883
785
|
|
|
884
|
-
const _tmpl$$1 = /*#__PURE__*/web.template(`<div
|
|
786
|
+
const _tmpl$$1 = /*#__PURE__*/web.template(`<div></div>`, 2),
|
|
787
|
+
_tmpl$2 = /*#__PURE__*/web.template(`<div><div></div></div>`, 4);
|
|
885
788
|
const PianoRoll = allProps => {
|
|
886
789
|
const [contextProps, divProps] = splitContextProps(allProps);
|
|
887
790
|
const [scrollerRef, setScrollerRef] = solidJs.createSignal();
|
|
@@ -891,14 +794,20 @@ const PianoRoll = allProps => {
|
|
|
891
794
|
const maxZoom = solidJs.createMemo(() => 500 * (zoomFactor / clientRect().width));
|
|
892
795
|
const minVerticalZoom = solidJs.createMemo(() => 1 / (zoomFactor / clientRect().height));
|
|
893
796
|
const maxVerticalZoom = solidJs.createMemo(() => 10 * (zoomFactor / clientRect().height));
|
|
797
|
+
solidJs.createEffect(isInitial => {
|
|
798
|
+
if (isInitial) return false;
|
|
799
|
+
if (contextProps.mode === "tracks") {
|
|
800
|
+
contextProps.onVerticalPositionChange?.(0);
|
|
801
|
+
}
|
|
802
|
+
}, true);
|
|
894
803
|
return web.createComponent(PianoRollContextProvider, {
|
|
895
804
|
value: contextProps,
|
|
896
805
|
get children() {
|
|
897
|
-
const _el$ = _tmpl
|
|
806
|
+
const _el$ = _tmpl$2.cloneNode(true),
|
|
898
807
|
_el$2 = _el$.firstChild;
|
|
899
808
|
web.spread(_el$, web.mergeProps(divProps, {
|
|
900
809
|
get ["class"]() {
|
|
901
|
-
return styles$
|
|
810
|
+
return styles$4.PianoRoll;
|
|
902
811
|
}
|
|
903
812
|
}), false, true);
|
|
904
813
|
web.insert(_el$2, web.createComponent(ScrollZoomViewPort, {
|
|
@@ -916,14 +825,35 @@ const PianoRoll = allProps => {
|
|
|
916
825
|
pixelOffset: clientRect().top,
|
|
917
826
|
pixelSize: clientRect().height,
|
|
918
827
|
position: contextProps.verticalPosition,
|
|
919
|
-
range: 128,
|
|
828
|
+
range: contextProps.mode === "keys" ? 128 : Math.max(contextProps.tracks.length, 16),
|
|
920
829
|
zoom: contextProps.verticalZoom * (zoomFactor / clientRect().height),
|
|
921
830
|
onPositionChange: contextProps.onVerticalPositionChange,
|
|
922
831
|
onZoomChange: verticalZoom => contextProps.onVerticalZoomChange?.(clamp(verticalZoom / (zoomFactor / clientRect().height), minVerticalZoom(), maxVerticalZoom()))
|
|
923
832
|
})
|
|
924
833
|
},
|
|
925
834
|
get children() {
|
|
926
|
-
return [
|
|
835
|
+
return [(() => {
|
|
836
|
+
const _el$3 = _tmpl$$1.cloneNode(true);
|
|
837
|
+
_el$3.style.setProperty("display", "flex");
|
|
838
|
+
_el$3.style.setProperty("width", "20%");
|
|
839
|
+
web.insert(_el$3, web.createComponent(solidJs.Show, {
|
|
840
|
+
get when() {
|
|
841
|
+
return allProps.showTrackList;
|
|
842
|
+
},
|
|
843
|
+
get children() {
|
|
844
|
+
return web.createComponent(PianoRollTrackList, {});
|
|
845
|
+
}
|
|
846
|
+
}), null);
|
|
847
|
+
web.insert(_el$3, web.createComponent(solidJs.Show, {
|
|
848
|
+
get when() {
|
|
849
|
+
return contextProps.mode === "keys";
|
|
850
|
+
},
|
|
851
|
+
get children() {
|
|
852
|
+
return web.createComponent(PianoRollKeys, {});
|
|
853
|
+
}
|
|
854
|
+
}), null);
|
|
855
|
+
return _el$3;
|
|
856
|
+
})(), web.createComponent(ScrollContainer, {
|
|
927
857
|
ref: setScrollerRef,
|
|
928
858
|
get children() {
|
|
929
859
|
return [web.memo(() => allProps.children), web.createComponent(PianoRollGrid, {}), web.createComponent(PianoRollNotes, {})];
|
|
@@ -946,7 +876,7 @@ const PianoRoll = allProps => {
|
|
|
946
876
|
return maxZoom();
|
|
947
877
|
}
|
|
948
878
|
}), null);
|
|
949
|
-
web.effect(() => web.className(_el$2, styles$
|
|
879
|
+
web.effect(() => web.className(_el$2, styles$4.PianoRollContainer));
|
|
950
880
|
return _el$;
|
|
951
881
|
}
|
|
952
882
|
});
|
|
@@ -1006,13 +936,37 @@ const PlayHead = allProps => {
|
|
|
1006
936
|
})();
|
|
1007
937
|
};
|
|
1008
938
|
|
|
939
|
+
const useNotes = () => {
|
|
940
|
+
const [notes, onNotesChange] = solidJs.createSignal([]);
|
|
941
|
+
const onNoteChange = (index, note) => {
|
|
942
|
+
onNotesChange([...notes().slice(0, index), note, ...notes().splice(index + 1)]);
|
|
943
|
+
};
|
|
944
|
+
const onInsertNote = note => {
|
|
945
|
+
const index = Math.max(notes().findIndex(({
|
|
946
|
+
ticks
|
|
947
|
+
}) => ticks > note.ticks), 0);
|
|
948
|
+
onNotesChange([...notes().slice(0, index), note, ...notes().splice(index)]);
|
|
949
|
+
return index;
|
|
950
|
+
};
|
|
951
|
+
const onRemoveNote = index => {
|
|
952
|
+
onNotesChange([...notes().slice(0, index), ...notes().splice(index + 1)]);
|
|
953
|
+
};
|
|
954
|
+
return {
|
|
955
|
+
notes,
|
|
956
|
+
onNotesChange,
|
|
957
|
+
onNoteChange,
|
|
958
|
+
onInsertNote,
|
|
959
|
+
onRemoveNote
|
|
960
|
+
};
|
|
961
|
+
};
|
|
962
|
+
|
|
1009
963
|
const usePianoRoll = () => {
|
|
1010
964
|
const [ppq, onPpqChange] = solidJs.createSignal(120);
|
|
1011
|
-
const [
|
|
965
|
+
const [mode, onModeChange] = solidJs.createSignal("tracks");
|
|
1012
966
|
const [position, onPositionChange] = solidJs.createSignal(0);
|
|
1013
967
|
const [zoom, onZoomChange] = solidJs.createSignal(10);
|
|
1014
968
|
const [verticalZoom, onVerticalZoomChange] = solidJs.createSignal(5);
|
|
1015
|
-
const [verticalPosition, onVerticalPositionChange] = solidJs.createSignal(
|
|
969
|
+
const [verticalPosition, onVerticalPositionChange] = solidJs.createSignal(44);
|
|
1016
970
|
const [gridDivision, onGridDivisionChange] = solidJs.createSignal(4);
|
|
1017
971
|
const [snapToGrid, onSnapToGridChange] = solidJs.createSignal(true);
|
|
1018
972
|
const [duration, onDurationChange] = solidJs.createSignal(0);
|
|
@@ -1031,14 +985,13 @@ const usePianoRoll = () => {
|
|
|
1031
985
|
onGridDivisionChange,
|
|
1032
986
|
snapToGrid,
|
|
1033
987
|
onSnapToGridChange,
|
|
1034
|
-
|
|
1035
|
-
|
|
988
|
+
mode,
|
|
989
|
+
onModeChange,
|
|
1036
990
|
duration,
|
|
1037
991
|
onDurationChange
|
|
1038
992
|
};
|
|
1039
993
|
};
|
|
1040
994
|
|
|
1041
|
-
exports.MultiTrackPianoRoll = MultiTrackPianoRoll;
|
|
1042
995
|
exports.PianoRoll = PianoRoll;
|
|
1043
996
|
exports.PlayHead = PlayHead;
|
|
1044
997
|
exports.useNotes = useNotes;
|