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