solid-pianoroll 0.0.14 → 0.0.16
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 +401 -418
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +404 -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/PianoRollKeys.jsx +24 -5
- 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,
|
|
1
|
+
import { createComponent, delegateEvents, insert, effect, className, classList, setAttribute, template, use, memo, spread, mergeProps } from 'solid-js/web';
|
|
2
|
+
import { createContext, splitProps, useContext, createEffect, createMemo, Index, createSignal, Show, 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 border-width: 0;\n border-color: #000;\n border-style: solid;\n border-right-width: 1px;\n border-left-width: 1px;\n background: white;\n cursor: pointer;\n overflow: hidden;\n}\n\n.PianoRollKeys-module_Key__jybNC {\n transition-property: background-color, box-shadow;\n transition-duration: 400ms;\n transition-timing-function: ease-out;\n border-width: 0px;\n position: absolute;\n box-sizing: border-box;\n width: 120%;\n left: -20%;\n border-color: #000;\n border-style: solid;\n}\n\n.PianoRollKeys-module_black__7rncB {\n background: black;\n border-top-right-radius: 12%;\n border-bottom-right-radius: 12%;\n margin-left: -20%;\n z-index: 1;\n}\n\n.PianoRollKeys-module_white__fR2Lm {\n background: white;\n border-top-width: 0.5px;\n border-bottom-width: 0.5px;\n}\n\n.PianoRollKeys-module_down__GcNeZ {\n transition: none;\n background: red;\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","down":"PianoRollKeys-module_down__GcNeZ"};
|
|
45
|
+
styleInject(css_248z$3);
|
|
65
46
|
|
|
66
47
|
function createViewPortDimension(getState) {
|
|
67
48
|
const getStateWithFunctions = () => ({
|
|
@@ -135,6 +116,95 @@ 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 [isDown, setIsDown] = createSignal(false);
|
|
128
|
+
const virtualDimensions = createMemo(() => viewPort().calculatePixelDimensions(127 - key().number, 1));
|
|
129
|
+
const previousIsBlack = blackKeys.includes((key().number - 1) % 12);
|
|
130
|
+
const nextIsBlack = blackKeys.includes((key().number + 1) % 12);
|
|
131
|
+
return createComponent(Show, {
|
|
132
|
+
get when() {
|
|
133
|
+
return virtualDimensions().size > 0;
|
|
134
|
+
},
|
|
135
|
+
get children() {
|
|
136
|
+
const _el$2 = _tmpl$$8.cloneNode(true);
|
|
137
|
+
_el$2.$$mouseup = () => setIsDown(false);
|
|
138
|
+
_el$2.$$mousedown = () => setIsDown(true);
|
|
139
|
+
insert(_el$2, createComponent(Show, {
|
|
140
|
+
get when() {
|
|
141
|
+
return key().isBlack && false;
|
|
142
|
+
},
|
|
143
|
+
get children() {
|
|
144
|
+
const _el$3 = _tmpl$$8.cloneNode(true);
|
|
145
|
+
effect(_p$ => {
|
|
146
|
+
const _v$ = styles$3["black-separator"],
|
|
147
|
+
_v$2 = `${virtualDimensions().offset}px`,
|
|
148
|
+
_v$3 = `${virtualDimensions().size / 2 - 0.25}px`;
|
|
149
|
+
_v$ !== _p$._v$ && className(_el$3, _p$._v$ = _v$);
|
|
150
|
+
_v$2 !== _p$._v$2 && _el$3.style.setProperty("top", _p$._v$2 = _v$2);
|
|
151
|
+
_v$3 !== _p$._v$3 && _el$3.style.setProperty("height", _p$._v$3 = _v$3);
|
|
152
|
+
return _p$;
|
|
153
|
+
}, {
|
|
154
|
+
_v$: undefined,
|
|
155
|
+
_v$2: undefined,
|
|
156
|
+
_v$3: undefined
|
|
157
|
+
});
|
|
158
|
+
return _el$3;
|
|
159
|
+
}
|
|
160
|
+
}));
|
|
161
|
+
effect(_p$ => {
|
|
162
|
+
const _v$4 = {
|
|
163
|
+
[styles$3["Key"]]: true,
|
|
164
|
+
[styles$3["black"]]: key().isBlack,
|
|
165
|
+
[styles$3["white"]]: !key().isBlack,
|
|
166
|
+
[styles$3["down"]]: isDown()
|
|
167
|
+
},
|
|
168
|
+
_v$5 = key().name,
|
|
169
|
+
_v$6 = key().number % 12,
|
|
170
|
+
_v$7 = `${virtualDimensions().offset - (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0)}px`,
|
|
171
|
+
_v$8 = `${virtualDimensions().size + (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0) + (!key().isBlack && previousIsBlack ? virtualDimensions().size / 2 : 0)}px`,
|
|
172
|
+
_v$9 = [`0px 0px ${Math.min(virtualDimensions().size / 20, 1)}px ${Math.min(virtualDimensions().size / 50, 1)}px rgba(0, 0, 0, 0.5) ${key().isBlack ? "" : "inset"}`, isDown() && `0px 0px ${Math.min(virtualDimensions().size / 8, 2)}px ${Math.min(virtualDimensions().size / 20, 2)}px rgba(0, 0, 0, 0.5) inset`].filter(item => !!item).join(", ");
|
|
173
|
+
_p$._v$4 = classList(_el$2, _v$4, _p$._v$4);
|
|
174
|
+
_v$5 !== _p$._v$5 && setAttribute(_el$2, "title", _p$._v$5 = _v$5);
|
|
175
|
+
_v$6 !== _p$._v$6 && setAttribute(_el$2, "data-index", _p$._v$6 = _v$6);
|
|
176
|
+
_v$7 !== _p$._v$7 && _el$2.style.setProperty("top", _p$._v$7 = _v$7);
|
|
177
|
+
_v$8 !== _p$._v$8 && _el$2.style.setProperty("height", _p$._v$8 = _v$8);
|
|
178
|
+
_v$9 !== _p$._v$9 && _el$2.style.setProperty("box-shadow", _p$._v$9 = _v$9);
|
|
179
|
+
return _p$;
|
|
180
|
+
}, {
|
|
181
|
+
_v$4: undefined,
|
|
182
|
+
_v$5: undefined,
|
|
183
|
+
_v$6: undefined,
|
|
184
|
+
_v$7: undefined,
|
|
185
|
+
_v$8: undefined,
|
|
186
|
+
_v$9: undefined
|
|
187
|
+
});
|
|
188
|
+
return _el$2;
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}));
|
|
193
|
+
effect(() => className(_el$, styles$3.PianoRollKeys));
|
|
194
|
+
return _el$;
|
|
195
|
+
})();
|
|
196
|
+
};
|
|
197
|
+
const blackKeys = [1, 3, 6, 8, 10];
|
|
198
|
+
const keyNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
199
|
+
const keys = Array.from({
|
|
200
|
+
length: 128
|
|
201
|
+
}).map((_, index) => ({
|
|
202
|
+
number: index,
|
|
203
|
+
name: `${keyNames[index % 12]} ${Math.floor(index / 12) - 2}`,
|
|
204
|
+
isBlack: blackKeys.includes(index % 12)
|
|
205
|
+
}));
|
|
206
|
+
delegateEvents(["mousedown", "mouseup"]);
|
|
207
|
+
|
|
138
208
|
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
209
|
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
210
|
styleInject(css_248z$2);
|
|
@@ -148,10 +218,11 @@ const PianoRollNotes = props => {
|
|
|
148
218
|
const snapValueToGridIfEnabled = (value, altKey) => context.snapToGrid && !altKey ? Math.round(value / gridDivisionTicks()) * gridDivisionTicks() : value;
|
|
149
219
|
const insertOrUpdateNote = event => {
|
|
150
220
|
const position = horizontalViewPort().calculatePosition(event.clientX);
|
|
151
|
-
const
|
|
221
|
+
const existingNote = currentNote();
|
|
222
|
+
const midi = context.mode === "keys" ? 127 - Math.floor(verticalViewPort().calculatePosition(event.clientY)) : existingNote?.midi ?? 60;
|
|
223
|
+
const targetTrackIndex = context.mode === "tracks" ? Math.floor(verticalViewPort().calculatePosition(event.clientY)) : context.selectedTrackIndex ?? 0;
|
|
152
224
|
const eventPositionTicks = Math.floor(position / gridDivisionTicks()) * gridDivisionTicks();
|
|
153
225
|
const velocity = 127;
|
|
154
|
-
const existingNote = newNote();
|
|
155
226
|
const ticks = existingNote?.ticks ?? eventPositionTicks;
|
|
156
227
|
const durationTicks = existingNote?.ticks ? eventPositionTicks - existingNote?.ticks : gridDivisionTicks();
|
|
157
228
|
const note = {
|
|
@@ -161,25 +232,26 @@ const PianoRollNotes = props => {
|
|
|
161
232
|
velocity
|
|
162
233
|
};
|
|
163
234
|
if (existingNote) {
|
|
164
|
-
context.onNoteChange?.(
|
|
165
|
-
return
|
|
235
|
+
context.onNoteChange?.(currentNoteTrackIndex(), currentNoteIndex(), note);
|
|
236
|
+
return currentNoteIndex();
|
|
166
237
|
} else {
|
|
167
|
-
return context.onInsertNote?.(note) ?? -1;
|
|
238
|
+
return context.onInsertNote?.(targetTrackIndex, note) ?? -1;
|
|
168
239
|
}
|
|
169
240
|
};
|
|
170
241
|
const [isDragging, setIsDragging] = createSignal(false);
|
|
171
242
|
const [noteDragMode, setNoteDragMode] = createSignal();
|
|
172
|
-
const [
|
|
243
|
+
const [currentNoteIndex, setCurrentNoteIndex] = createSignal(-1);
|
|
244
|
+
const [currentNoteTrackIndex, setCurrentNoteTrackIndex] = createSignal(-1);
|
|
173
245
|
const [isMouseDown, setIsMouseDown] = createSignal(false);
|
|
174
|
-
const
|
|
246
|
+
const currentNote = createMemo(() => context.tracks[currentNoteTrackIndex()]?.notes[currentNoteIndex()]);
|
|
175
247
|
const getClasses = noteDragMode => {
|
|
176
248
|
return noteDragMode ? [styles$2.Note, styles$2[noteDragMode]] : [styles$2.Note];
|
|
177
249
|
};
|
|
178
250
|
return (() => {
|
|
179
251
|
const _el$ = _tmpl$$7.cloneNode(true);
|
|
180
252
|
_el$.$$click = event => {
|
|
181
|
-
if (
|
|
182
|
-
|
|
253
|
+
if (currentNote()) {
|
|
254
|
+
setCurrentNoteIndex(-1);
|
|
183
255
|
return;
|
|
184
256
|
}
|
|
185
257
|
if (!event.altKey) return;
|
|
@@ -200,94 +272,133 @@ const PianoRollNotes = props => {
|
|
|
200
272
|
return;
|
|
201
273
|
}
|
|
202
274
|
const index = insertOrUpdateNote(event);
|
|
203
|
-
|
|
275
|
+
setCurrentNoteIndex(index);
|
|
204
276
|
};
|
|
205
277
|
_el$.$$mousedown = event => {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
278
|
+
batch(() => {
|
|
279
|
+
setIsMouseDown(true);
|
|
280
|
+
const index = insertOrUpdateNote(event);
|
|
281
|
+
setCurrentNoteTrackIndex(context.selectedTrackIndex ?? 0);
|
|
282
|
+
setCurrentNoteIndex(index);
|
|
283
|
+
});
|
|
210
284
|
};
|
|
211
285
|
const _ref$ = props.ref;
|
|
212
286
|
typeof _ref$ === "function" ? use(_ref$, _el$) : props.ref = _el$;
|
|
213
|
-
insert(_el$, createComponent(
|
|
287
|
+
insert(_el$, createComponent(For, {
|
|
214
288
|
get each() {
|
|
215
|
-
return context.
|
|
289
|
+
return context.tracks;
|
|
216
290
|
},
|
|
217
|
-
children: (
|
|
218
|
-
const verticalVirtualDimensions = createMemo(() => verticalViewPort().calculatePixelDimensions(127 - note().midi, 1));
|
|
219
|
-
const horizontalDimensions = createMemo(() => horizontalViewPort().calculatePixelDimensions(note().ticks, note().durationTicks));
|
|
291
|
+
children: (track, trackIndex) => {
|
|
220
292
|
return createComponent(Show, {
|
|
221
293
|
get when() {
|
|
222
|
-
return
|
|
294
|
+
return trackIndex() === context.selectedTrackIndex || context.showAllTracks || context.mode === "tracks";
|
|
223
295
|
},
|
|
224
296
|
get children() {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
297
|
+
return createComponent(For, {
|
|
298
|
+
get each() {
|
|
299
|
+
return track.notes;
|
|
300
|
+
},
|
|
301
|
+
children: (note, noteIndex) => {
|
|
302
|
+
const verticalVirtualDimensions = createMemo(() => verticalViewPort().calculatePixelDimensions(context.mode === "keys" ? 127 - note.midi : trackIndex(), 1));
|
|
303
|
+
const horizontalDimensions = createMemo(() => horizontalViewPort().calculatePixelDimensions(note.ticks, note.durationTicks));
|
|
304
|
+
return createComponent(Show, {
|
|
305
|
+
get when() {
|
|
306
|
+
return memo(() => !!verticalViewPort().isVisible(verticalVirtualDimensions()))() && horizontalViewPort().isVisible(horizontalDimensions());
|
|
307
|
+
},
|
|
308
|
+
get children() {
|
|
309
|
+
const _el$2 = _tmpl$$7.cloneNode(true);
|
|
310
|
+
_el$2.$$mousedown = event => {
|
|
311
|
+
event.stopPropagation();
|
|
312
|
+
setIsDragging(true);
|
|
313
|
+
setCurrentNoteIndex(noteIndex());
|
|
314
|
+
setCurrentNoteTrackIndex(trackIndex());
|
|
315
|
+
const initialPosition = horizontalViewPort().calculatePosition(event.clientX);
|
|
316
|
+
const diffPosition = initialPosition - note.ticks;
|
|
317
|
+
const handleMouseMove = mouseMoveEvent => {
|
|
318
|
+
const note = currentNote();
|
|
319
|
+
if (!note) return;
|
|
320
|
+
const ticks = snapValueToGridIfEnabled(Math.max(horizontalViewPort().calculatePosition(mouseMoveEvent.clientX) - diffPosition, 0), mouseMoveEvent.altKey);
|
|
321
|
+
const updatedNote = {
|
|
322
|
+
...note,
|
|
323
|
+
...(noteDragMode() === "move" && context.mode === "keys" && {
|
|
324
|
+
midi: Math.round(127 - verticalViewPort().calculatePosition(mouseMoveEvent.clientY))
|
|
325
|
+
}),
|
|
326
|
+
...((noteDragMode() === "move" || noteDragMode() === "trimStart") && {
|
|
327
|
+
ticks
|
|
328
|
+
}),
|
|
329
|
+
...(noteDragMode() === "trimStart" && {
|
|
330
|
+
durationTicks: note.durationTicks + note.ticks - ticks
|
|
331
|
+
}),
|
|
332
|
+
...(noteDragMode() === "trimEnd" && {
|
|
333
|
+
durationTicks: snapValueToGridIfEnabled(horizontalViewPort().calculatePosition(mouseMoveEvent.clientX) - note.ticks, mouseMoveEvent.altKey)
|
|
334
|
+
})
|
|
335
|
+
};
|
|
336
|
+
const previousTrackIndex = currentNoteTrackIndex();
|
|
337
|
+
const previousNoteIndex = currentNoteIndex();
|
|
338
|
+
const targetTrackIndex = context.mode === "tracks" ? Math.floor(verticalViewPort().calculatePosition(mouseMoveEvent.clientY)) : previousTrackIndex;
|
|
339
|
+
if (targetTrackIndex === previousTrackIndex) {
|
|
340
|
+
context.onNoteChange?.(previousTrackIndex, previousNoteIndex, updatedNote);
|
|
341
|
+
} else {
|
|
342
|
+
batch(() => {
|
|
343
|
+
if (context.onInsertNote) {
|
|
344
|
+
context.onRemoveNote?.(previousTrackIndex, previousNoteIndex);
|
|
345
|
+
const newNoteIndex = context.onInsertNote(targetTrackIndex, updatedNote);
|
|
346
|
+
setCurrentNoteTrackIndex(targetTrackIndex);
|
|
347
|
+
setCurrentNoteIndex(newNoteIndex);
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
const handleMouseUp = () => {
|
|
353
|
+
setIsDragging(false);
|
|
354
|
+
setCurrentNoteIndex(-1);
|
|
355
|
+
setCurrentNoteTrackIndex(-1);
|
|
356
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
357
|
+
window.removeEventListener("mouseup", handleMouseUp);
|
|
358
|
+
};
|
|
359
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
360
|
+
window.addEventListener("mouseup", handleMouseUp);
|
|
361
|
+
};
|
|
362
|
+
_el$2.$$dblclick = event => {
|
|
363
|
+
event.stopPropagation();
|
|
364
|
+
context.onRemoveNote?.(trackIndex(), noteIndex());
|
|
365
|
+
};
|
|
366
|
+
_el$2.$$mousemove = event => {
|
|
367
|
+
if (isDragging()) return;
|
|
368
|
+
event.stopPropagation();
|
|
369
|
+
const relativeX = horizontalViewPort().calculatePixelValue(horizontalViewPort().calculatePosition(event.clientX));
|
|
370
|
+
const noteStartX = horizontalViewPort().calculatePixelValue(note.ticks);
|
|
371
|
+
const noteEndX = horizontalViewPort().calculatePixelValue(note.ticks + note.durationTicks);
|
|
372
|
+
setNoteDragMode(relativeX - noteStartX < 3 ? "trimStart" : noteEndX - relativeX < 3 ? "trimEnd" : "move");
|
|
373
|
+
};
|
|
374
|
+
setAttribute(_el$2, "draggable", false);
|
|
375
|
+
effect(_p$ => {
|
|
376
|
+
const _v$ = getClasses(noteDragMode()).join(" "),
|
|
377
|
+
_v$2 = `rgba(255,0,0, ${(128 + note.velocity) / 256})`,
|
|
378
|
+
_v$3 = `${verticalVirtualDimensions().offset}px`,
|
|
379
|
+
_v$4 = `${verticalVirtualDimensions().size}px`,
|
|
380
|
+
_v$5 = `${horizontalDimensions().offset}px`,
|
|
381
|
+
_v$6 = `${horizontalDimensions().size}px`;
|
|
382
|
+
_v$ !== _p$._v$ && className(_el$2, _p$._v$ = _v$);
|
|
383
|
+
_v$2 !== _p$._v$2 && _el$2.style.setProperty("background-color", _p$._v$2 = _v$2);
|
|
384
|
+
_v$3 !== _p$._v$3 && _el$2.style.setProperty("top", _p$._v$3 = _v$3);
|
|
385
|
+
_v$4 !== _p$._v$4 && _el$2.style.setProperty("height", _p$._v$4 = _v$4);
|
|
386
|
+
_v$5 !== _p$._v$5 && _el$2.style.setProperty("left", _p$._v$5 = _v$5);
|
|
387
|
+
_v$6 !== _p$._v$6 && _el$2.style.setProperty("width", _p$._v$6 = _v$6);
|
|
388
|
+
return _p$;
|
|
389
|
+
}, {
|
|
390
|
+
_v$: undefined,
|
|
391
|
+
_v$2: undefined,
|
|
392
|
+
_v$3: undefined,
|
|
393
|
+
_v$4: undefined,
|
|
394
|
+
_v$5: undefined,
|
|
395
|
+
_v$6: undefined
|
|
396
|
+
});
|
|
397
|
+
return _el$2;
|
|
398
|
+
}
|
|
247
399
|
});
|
|
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
|
|
400
|
+
}
|
|
289
401
|
});
|
|
290
|
-
return _el$2;
|
|
291
402
|
}
|
|
292
403
|
});
|
|
293
404
|
}
|
|
@@ -401,74 +512,11 @@ const ScrollContainer = props => {
|
|
|
401
512
|
})();
|
|
402
513
|
};
|
|
403
514
|
|
|
404
|
-
var css_248z$1 = ".
|
|
405
|
-
var styles$1 = {"
|
|
515
|
+
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";
|
|
516
|
+
var styles$1 = {"PianoRollGrid":"PianoRollGrid-module_PianoRollGrid__tG119","PianoRollGrid-Row":"PianoRollGrid-module_PianoRollGrid-Row__nRMCs","PianoRollGrid-Time":"PianoRollGrid-module_PianoRollGrid-Time__jLz3E"};
|
|
406
517
|
styleInject(css_248z$1);
|
|
407
518
|
|
|
408
519
|
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
520
|
const PianoRollGrid = () => {
|
|
473
521
|
const context = usePianoRollContext();
|
|
474
522
|
const verticalViewPort = createMemo(() => useViewPortDimension("vertical"));
|
|
@@ -498,7 +546,7 @@ const PianoRollGrid = () => {
|
|
|
498
546
|
}));
|
|
499
547
|
});
|
|
500
548
|
return (() => {
|
|
501
|
-
const _el$ = _tmpl$$
|
|
549
|
+
const _el$ = _tmpl$$5.cloneNode(true);
|
|
502
550
|
insert(_el$, createComponent(Index, {
|
|
503
551
|
get each() {
|
|
504
552
|
return gridArray();
|
|
@@ -510,9 +558,9 @@ const PianoRollGrid = () => {
|
|
|
510
558
|
return virtualDimensions().size > 0;
|
|
511
559
|
},
|
|
512
560
|
get children() {
|
|
513
|
-
const _el$2 = _tmpl$$
|
|
561
|
+
const _el$2 = _tmpl$$5.cloneNode(true);
|
|
514
562
|
effect(_p$ => {
|
|
515
|
-
const _v$ = styles["PianoRollGrid-Time"],
|
|
563
|
+
const _v$ = styles$1["PianoRollGrid-Time"],
|
|
516
564
|
_v$2 = Math.ceil((entry().index + 1 * selectedGridDivisorTicks()) / measureTicks()) % 2 === 0 ? "#ddd" : "#ccc",
|
|
517
565
|
_v$3 = `${virtualDimensions().offset}px`,
|
|
518
566
|
_v$4 = `${virtualDimensions().size}px`,
|
|
@@ -537,7 +585,7 @@ const PianoRollGrid = () => {
|
|
|
537
585
|
}), null);
|
|
538
586
|
insert(_el$, createComponent(Show, {
|
|
539
587
|
get when() {
|
|
540
|
-
return
|
|
588
|
+
return context.mode === "keys";
|
|
541
589
|
},
|
|
542
590
|
get children() {
|
|
543
591
|
return createComponent(Index, {
|
|
@@ -549,10 +597,10 @@ const PianoRollGrid = () => {
|
|
|
549
597
|
return virtualDimensions().size > 0;
|
|
550
598
|
},
|
|
551
599
|
get children() {
|
|
552
|
-
const _el$3 = _tmpl$$
|
|
600
|
+
const _el$3 = _tmpl$$5.cloneNode(true);
|
|
553
601
|
_el$3.style.setProperty("width", "100%");
|
|
554
602
|
effect(_p$ => {
|
|
555
|
-
const _v$6 = styles["PianoRollGrid-
|
|
603
|
+
const _v$6 = styles$1["PianoRollGrid-Row"],
|
|
556
604
|
_v$7 = `${virtualDimensions().offset}px`,
|
|
557
605
|
_v$8 = `${virtualDimensions().size}px`,
|
|
558
606
|
_v$9 = key().isBlack ? "rgba(0,0,0,0.2)" : "none",
|
|
@@ -577,35 +625,53 @@ const PianoRollGrid = () => {
|
|
|
577
625
|
});
|
|
578
626
|
}
|
|
579
627
|
}), null);
|
|
580
|
-
|
|
628
|
+
insert(_el$, createComponent(Show, {
|
|
629
|
+
get when() {
|
|
630
|
+
return context.mode === "tracks";
|
|
631
|
+
},
|
|
632
|
+
get children() {
|
|
633
|
+
return createComponent(For, {
|
|
634
|
+
get each() {
|
|
635
|
+
return context.tracks;
|
|
636
|
+
},
|
|
637
|
+
children: (track, index) => {
|
|
638
|
+
const virtualDimensions = createMemo(() => verticalViewPort().calculatePixelDimensions(index(), 1));
|
|
639
|
+
return createComponent(Show, {
|
|
640
|
+
get when() {
|
|
641
|
+
return virtualDimensions().size > 0;
|
|
642
|
+
},
|
|
643
|
+
get children() {
|
|
644
|
+
const _el$4 = _tmpl$$5.cloneNode(true);
|
|
645
|
+
_el$4.style.setProperty("width", "100%");
|
|
646
|
+
_el$4.style.setProperty("border-width", "0");
|
|
647
|
+
effect(_p$ => {
|
|
648
|
+
const _v$11 = styles$1["PianoRollGrid-Row"],
|
|
649
|
+
_v$12 = `${virtualDimensions().offset}px`,
|
|
650
|
+
_v$13 = `${virtualDimensions().size}px`,
|
|
651
|
+
_v$14 = index() % 2 === 0 ? "rgba(0,0,0,0.2)" : "none";
|
|
652
|
+
_v$11 !== _p$._v$11 && className(_el$4, _p$._v$11 = _v$11);
|
|
653
|
+
_v$12 !== _p$._v$12 && _el$4.style.setProperty("top", _p$._v$12 = _v$12);
|
|
654
|
+
_v$13 !== _p$._v$13 && _el$4.style.setProperty("height", _p$._v$13 = _v$13);
|
|
655
|
+
_v$14 !== _p$._v$14 && _el$4.style.setProperty("background-color", _p$._v$14 = _v$14);
|
|
656
|
+
return _p$;
|
|
657
|
+
}, {
|
|
658
|
+
_v$11: undefined,
|
|
659
|
+
_v$12: undefined,
|
|
660
|
+
_v$13: undefined,
|
|
661
|
+
_v$14: undefined
|
|
662
|
+
});
|
|
663
|
+
return _el$4;
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
}), null);
|
|
670
|
+
effect(() => className(_el$, styles$1.PianoRollGrid));
|
|
581
671
|
return _el$;
|
|
582
672
|
})();
|
|
583
673
|
};
|
|
584
674
|
|
|
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
675
|
const defaultRect = {
|
|
610
676
|
left: 0,
|
|
611
677
|
width: 0,
|
|
@@ -634,11 +700,11 @@ function useBoundingClientRect(containerRef) {
|
|
|
634
700
|
return boundingClientRect;
|
|
635
701
|
}
|
|
636
702
|
|
|
637
|
-
const _tmpl$$
|
|
703
|
+
const _tmpl$$4 = /*#__PURE__*/template(`<input min="1" max="11" step="0.01">`, 1);
|
|
638
704
|
const VerticalZoomControl = props => {
|
|
639
705
|
const context = usePianoRollContext();
|
|
640
706
|
return (() => {
|
|
641
|
-
const _el$ = _tmpl$$
|
|
707
|
+
const _el$ = _tmpl$$4.cloneNode(true);
|
|
642
708
|
spread(_el$, mergeProps(props, {
|
|
643
709
|
get value() {
|
|
644
710
|
return context.verticalZoom;
|
|
@@ -662,224 +728,91 @@ const VerticalZoomControl = props => {
|
|
|
662
728
|
})();
|
|
663
729
|
};
|
|
664
730
|
|
|
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));
|
|
731
|
+
const _tmpl$$3 = /*#__PURE__*/template(`<input max="500" min="1" step="0.01">`, 1);
|
|
732
|
+
const HorizontalZoomControl = props => {
|
|
733
|
+
const context = usePianoRollContext();
|
|
688
734
|
return (() => {
|
|
689
|
-
const _el$ = _tmpl
|
|
690
|
-
spread(_el$, mergeProps(
|
|
735
|
+
const _el$ = _tmpl$$3.cloneNode(true);
|
|
736
|
+
spread(_el$, mergeProps(props, {
|
|
737
|
+
get value() {
|
|
738
|
+
return context.zoom;
|
|
739
|
+
},
|
|
740
|
+
"onInput": event => context.onZoomChange?.(event.currentTarget.valueAsNumber),
|
|
741
|
+
"type": "range",
|
|
691
742
|
get style() {
|
|
692
743
|
return {
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
"flex-direction": "row",
|
|
697
|
-
overflow: "hidden",
|
|
698
|
-
...(typeof divProps.style === "object" && divProps.style)
|
|
744
|
+
"margin-left": "50px",
|
|
745
|
+
"margin-right": "16px",
|
|
746
|
+
...(typeof props.style === "object" && props.style)
|
|
699
747
|
};
|
|
700
748
|
}
|
|
701
|
-
}), false,
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
749
|
+
}), false, false);
|
|
750
|
+
return _el$;
|
|
751
|
+
})();
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
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";
|
|
755
|
+
var styles = {"PianoRollTrackList":"PianoRollTrackList-module_PianoRollTrackList__pyuxQ","Track":"PianoRollTrackList-module_Track__VZFIg"};
|
|
756
|
+
styleInject(css_248z);
|
|
757
|
+
|
|
758
|
+
const _tmpl$$2 = /*#__PURE__*/template(`<div></div>`, 2),
|
|
759
|
+
_tmpl$2$1 = /*#__PURE__*/template(`<div> </div>`, 2);
|
|
760
|
+
const PianoRollTrackList = () => {
|
|
761
|
+
const viewPort = createMemo(() => useViewPortDimension("vertical"));
|
|
762
|
+
const context = usePianoRollContext();
|
|
763
|
+
return (() => {
|
|
764
|
+
const _el$ = _tmpl$$2.cloneNode(true);
|
|
765
|
+
insert(_el$, createComponent(Index, {
|
|
766
|
+
get each() {
|
|
767
|
+
return context.tracks;
|
|
707
768
|
},
|
|
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
|
-
})
|
|
769
|
+
children: (track, index) => {
|
|
770
|
+
const virtualDimensions = createMemo(() => viewPort().calculatePixelDimensions(context.mode === "tracks" ? index : index * 8, context.mode === "tracks" ? 1 : 8));
|
|
771
|
+
return createComponent(Show, {
|
|
772
|
+
get when() {
|
|
773
|
+
return virtualDimensions().size > 0;
|
|
729
774
|
},
|
|
730
775
|
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;
|
|
776
|
+
const _el$2 = _tmpl$2$1.cloneNode(true),
|
|
777
|
+
_el$3 = _el$2.firstChild;
|
|
778
|
+
_el$2.$$click = () => context.onSelectedTrackIndexChange?.(index);
|
|
779
|
+
_el$2.style.setProperty("cursor", "pointer");
|
|
780
|
+
insert(_el$2, index, _el$3);
|
|
781
|
+
insert(_el$2, () => track().name || "[unnamed track]", null);
|
|
782
|
+
effect(_p$ => {
|
|
783
|
+
const _v$ = {
|
|
784
|
+
[styles["Track"]]: true
|
|
858
785
|
},
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
786
|
+
_v$2 = track().name,
|
|
787
|
+
_v$3 = `${virtualDimensions().offset}px`,
|
|
788
|
+
_v$4 = `${virtualDimensions().size}px`,
|
|
789
|
+
_v$5 = index === context.selectedTrackIndex ? "gray" : "lightgrey";
|
|
790
|
+
_p$._v$ = classList(_el$2, _v$, _p$._v$);
|
|
791
|
+
_v$2 !== _p$._v$2 && setAttribute(_el$2, "title", _p$._v$2 = _v$2);
|
|
792
|
+
_v$3 !== _p$._v$3 && _el$2.style.setProperty("top", _p$._v$3 = _v$3);
|
|
793
|
+
_v$4 !== _p$._v$4 && _el$2.style.setProperty("height", _p$._v$4 = _v$4);
|
|
794
|
+
_v$5 !== _p$._v$5 && _el$2.style.setProperty("background", _p$._v$5 = _v$5);
|
|
795
|
+
return _p$;
|
|
796
|
+
}, {
|
|
797
|
+
_v$: undefined,
|
|
798
|
+
_v$2: undefined,
|
|
799
|
+
_v$3: undefined,
|
|
800
|
+
_v$4: undefined,
|
|
801
|
+
_v$5: undefined
|
|
802
|
+
});
|
|
803
|
+
return _el$2;
|
|
873
804
|
}
|
|
874
805
|
});
|
|
875
806
|
}
|
|
876
807
|
}));
|
|
808
|
+
effect(() => className(_el$, styles.PianoRollTrackList));
|
|
877
809
|
return _el$;
|
|
878
810
|
})();
|
|
879
811
|
};
|
|
880
812
|
delegateEvents(["click"]);
|
|
881
813
|
|
|
882
|
-
const _tmpl$$1 = /*#__PURE__*/template(`<div
|
|
814
|
+
const _tmpl$$1 = /*#__PURE__*/template(`<div></div>`, 2),
|
|
815
|
+
_tmpl$2 = /*#__PURE__*/template(`<div><div></div></div>`, 4);
|
|
883
816
|
const PianoRoll = allProps => {
|
|
884
817
|
const [contextProps, divProps] = splitContextProps(allProps);
|
|
885
818
|
const [scrollerRef, setScrollerRef] = createSignal();
|
|
@@ -889,14 +822,20 @@ const PianoRoll = allProps => {
|
|
|
889
822
|
const maxZoom = createMemo(() => 500 * (zoomFactor / clientRect().width));
|
|
890
823
|
const minVerticalZoom = createMemo(() => 1 / (zoomFactor / clientRect().height));
|
|
891
824
|
const maxVerticalZoom = createMemo(() => 10 * (zoomFactor / clientRect().height));
|
|
825
|
+
createEffect(isInitial => {
|
|
826
|
+
if (isInitial) return false;
|
|
827
|
+
if (contextProps.mode === "tracks") {
|
|
828
|
+
contextProps.onVerticalPositionChange?.(0);
|
|
829
|
+
}
|
|
830
|
+
}, true);
|
|
892
831
|
return createComponent(PianoRollContextProvider, {
|
|
893
832
|
value: contextProps,
|
|
894
833
|
get children() {
|
|
895
|
-
const _el$ = _tmpl
|
|
834
|
+
const _el$ = _tmpl$2.cloneNode(true),
|
|
896
835
|
_el$2 = _el$.firstChild;
|
|
897
836
|
spread(_el$, mergeProps(divProps, {
|
|
898
837
|
get ["class"]() {
|
|
899
|
-
return styles$
|
|
838
|
+
return styles$4.PianoRoll;
|
|
900
839
|
}
|
|
901
840
|
}), false, true);
|
|
902
841
|
insert(_el$2, createComponent(ScrollZoomViewPort, {
|
|
@@ -914,14 +853,35 @@ const PianoRoll = allProps => {
|
|
|
914
853
|
pixelOffset: clientRect().top,
|
|
915
854
|
pixelSize: clientRect().height,
|
|
916
855
|
position: contextProps.verticalPosition,
|
|
917
|
-
range: 128,
|
|
856
|
+
range: contextProps.mode === "keys" ? 128 : Math.max(contextProps.tracks.length, 16),
|
|
918
857
|
zoom: contextProps.verticalZoom * (zoomFactor / clientRect().height),
|
|
919
858
|
onPositionChange: contextProps.onVerticalPositionChange,
|
|
920
859
|
onZoomChange: verticalZoom => contextProps.onVerticalZoomChange?.(clamp(verticalZoom / (zoomFactor / clientRect().height), minVerticalZoom(), maxVerticalZoom()))
|
|
921
860
|
})
|
|
922
861
|
},
|
|
923
862
|
get children() {
|
|
924
|
-
return [
|
|
863
|
+
return [(() => {
|
|
864
|
+
const _el$3 = _tmpl$$1.cloneNode(true);
|
|
865
|
+
_el$3.style.setProperty("display", "flex");
|
|
866
|
+
_el$3.style.setProperty("width", "20%");
|
|
867
|
+
insert(_el$3, createComponent(Show, {
|
|
868
|
+
get when() {
|
|
869
|
+
return allProps.showTrackList;
|
|
870
|
+
},
|
|
871
|
+
get children() {
|
|
872
|
+
return createComponent(PianoRollTrackList, {});
|
|
873
|
+
}
|
|
874
|
+
}), null);
|
|
875
|
+
insert(_el$3, createComponent(Show, {
|
|
876
|
+
get when() {
|
|
877
|
+
return contextProps.mode === "keys";
|
|
878
|
+
},
|
|
879
|
+
get children() {
|
|
880
|
+
return createComponent(PianoRollKeys, {});
|
|
881
|
+
}
|
|
882
|
+
}), null);
|
|
883
|
+
return _el$3;
|
|
884
|
+
})(), createComponent(ScrollContainer, {
|
|
925
885
|
ref: setScrollerRef,
|
|
926
886
|
get children() {
|
|
927
887
|
return [memo(() => allProps.children), createComponent(PianoRollGrid, {}), createComponent(PianoRollNotes, {})];
|
|
@@ -944,7 +904,7 @@ const PianoRoll = allProps => {
|
|
|
944
904
|
return maxZoom();
|
|
945
905
|
}
|
|
946
906
|
}), null);
|
|
947
|
-
effect(() => className(_el$2, styles$
|
|
907
|
+
effect(() => className(_el$2, styles$4.PianoRollContainer));
|
|
948
908
|
return _el$;
|
|
949
909
|
}
|
|
950
910
|
});
|
|
@@ -1004,13 +964,37 @@ const PlayHead = allProps => {
|
|
|
1004
964
|
})();
|
|
1005
965
|
};
|
|
1006
966
|
|
|
967
|
+
const useNotes = () => {
|
|
968
|
+
const [notes, onNotesChange] = createSignal([]);
|
|
969
|
+
const onNoteChange = (index, note) => {
|
|
970
|
+
onNotesChange([...notes().slice(0, index), note, ...notes().splice(index + 1)]);
|
|
971
|
+
};
|
|
972
|
+
const onInsertNote = note => {
|
|
973
|
+
const index = Math.max(notes().findIndex(({
|
|
974
|
+
ticks
|
|
975
|
+
}) => ticks > note.ticks), 0);
|
|
976
|
+
onNotesChange([...notes().slice(0, index), note, ...notes().splice(index)]);
|
|
977
|
+
return index;
|
|
978
|
+
};
|
|
979
|
+
const onRemoveNote = index => {
|
|
980
|
+
onNotesChange([...notes().slice(0, index), ...notes().splice(index + 1)]);
|
|
981
|
+
};
|
|
982
|
+
return {
|
|
983
|
+
notes,
|
|
984
|
+
onNotesChange,
|
|
985
|
+
onNoteChange,
|
|
986
|
+
onInsertNote,
|
|
987
|
+
onRemoveNote
|
|
988
|
+
};
|
|
989
|
+
};
|
|
990
|
+
|
|
1007
991
|
const usePianoRoll = () => {
|
|
1008
992
|
const [ppq, onPpqChange] = createSignal(120);
|
|
1009
|
-
const [
|
|
993
|
+
const [mode, onModeChange] = createSignal("tracks");
|
|
1010
994
|
const [position, onPositionChange] = createSignal(0);
|
|
1011
995
|
const [zoom, onZoomChange] = createSignal(10);
|
|
1012
996
|
const [verticalZoom, onVerticalZoomChange] = createSignal(5);
|
|
1013
|
-
const [verticalPosition, onVerticalPositionChange] = createSignal(
|
|
997
|
+
const [verticalPosition, onVerticalPositionChange] = createSignal(44);
|
|
1014
998
|
const [gridDivision, onGridDivisionChange] = createSignal(4);
|
|
1015
999
|
const [snapToGrid, onSnapToGridChange] = createSignal(true);
|
|
1016
1000
|
const [duration, onDurationChange] = createSignal(0);
|
|
@@ -1029,12 +1013,12 @@ const usePianoRoll = () => {
|
|
|
1029
1013
|
onGridDivisionChange,
|
|
1030
1014
|
snapToGrid,
|
|
1031
1015
|
onSnapToGridChange,
|
|
1032
|
-
|
|
1033
|
-
|
|
1016
|
+
mode,
|
|
1017
|
+
onModeChange,
|
|
1034
1018
|
duration,
|
|
1035
1019
|
onDurationChange
|
|
1036
1020
|
};
|
|
1037
1021
|
};
|
|
1038
1022
|
|
|
1039
|
-
export {
|
|
1023
|
+
export { PianoRoll, PlayHead, useNotes, usePianoRoll };
|
|
1040
1024
|
//# sourceMappingURL=index.js.map
|