solid-pianoroll 0.0.15 → 0.0.17
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 +423 -236
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +430 -243
- package/dist/esm/index.js.map +1 -1
- package/dist/source/PianoRoll.jsx +49 -25
- package/dist/source/PianoRollContext.jsx +27 -14
- package/dist/source/PianoRollGrid.jsx +1 -1
- package/dist/source/PianoRollKeys.jsx +59 -6
- package/dist/source/PianoRollNotes.jsx +4 -3
- package/dist/source/PianoRollTrackList.jsx +2 -2
- package/dist/source/index.jsx +2 -2
- package/dist/source/usePianoRollState.js +92 -0
- package/dist/source/viewport/HorizontalZoomControl.jsx +4 -3
- package/dist/source/viewport/ScrollContainer.jsx +27 -10
- package/dist/source/viewport/VerticalZoomControl.jsx +5 -3
- package/dist/types/PianoRoll.d.ts +3 -22
- package/dist/types/PianoRollContext.d.ts +73 -4
- package/dist/types/index.d.ts +2 -2
- package/dist/types/usePianoRollState.d.ts +52 -0
- package/dist/types/viewport/HorizontalZoomControl.d.ts +3 -1
- package/dist/types/viewport/ScrollContainer.d.ts +5 -2
- package/dist/types/viewport/ScrollZoomViewPort.d.ts +1 -1
- package/dist/types/viewport/VerticalZoomControl.d.ts +3 -1
- package/dist/types/viewport/createViewPortDimension.d.ts +2 -2
- package/package.json +1 -1
- package/dist/source/usePianoRoll.js +0 -33
- package/dist/types/usePianoRoll.d.ts +0 -22
package/dist/cjs/index.js
CHANGED
|
@@ -29,9 +29,9 @@ function styleInject(css, ref) {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
var css_248z$
|
|
33
|
-
var styles$
|
|
34
|
-
styleInject(css_248z$
|
|
32
|
+
var css_248z$5 = ".PianoRoll-module_PianoRoll__rkRYx {\n box-sizing: border-box;\n display: flex;\n overflow: hidden;\n flex-direction: column;\n height: 100%;\n}\n\n.PianoRoll-module_PianoRollContainer__Oyxr7 {\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: row;\n}\n";
|
|
33
|
+
var styles$5 = {"PianoRoll":"PianoRoll-module_PianoRoll__rkRYx","PianoRollContainer":"PianoRoll-module_PianoRollContainer__Oyxr7"};
|
|
34
|
+
styleInject(css_248z$5);
|
|
35
35
|
|
|
36
36
|
const PianoRollContext = solidJs.createContext();
|
|
37
37
|
const PianoRollContextProvider = PianoRollContext.Provider;
|
|
@@ -40,11 +40,11 @@ const usePianoRollContext = () => {
|
|
|
40
40
|
if (!context) throw new Error("No PianoRollContext found");
|
|
41
41
|
return context;
|
|
42
42
|
};
|
|
43
|
-
const splitContextProps = allProps => solidJs.splitProps(allProps, ["mode", "
|
|
43
|
+
const splitContextProps = allProps => solidJs.splitProps(allProps, ["ppq", "mode", "position", "zoom", "verticalZoom", "verticalPosition", "verticalTrackZoom", "verticalTrackPosition", "gridDivision", "snapToGrid", "duration", "tracks", "selectedTrackIndex", "pressedKeys", "onPpqChange", "onModeChange", "onPositionChange", "onZoomChange", "onVerticalZoomChange", "onVerticalPositionChange", "onVerticalTrackZoomChange", "onVerticalTrackPositionChange", "onGridDivisionChange", "onSnapToGridChange", "onDurationChange", "onTracksChange", "onNoteChange", "onInsertNote", "onRemoveNote", "onSelectedTrackIndexChange", "onPressedKeysChange", "showAllTracks", "showTrackList"]);
|
|
44
44
|
|
|
45
|
-
var css_248z$
|
|
46
|
-
var styles$
|
|
47
|
-
styleInject(css_248z$
|
|
45
|
+
var css_248z$4 = ".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: 200ms;\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";
|
|
46
|
+
var styles$4 = {"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"};
|
|
47
|
+
styleInject(css_248z$4);
|
|
48
48
|
|
|
49
49
|
function createViewPortDimension(getState) {
|
|
50
50
|
const getStateWithFunctions = () => ({
|
|
@@ -118,55 +118,248 @@ const useViewPortDimension = name => {
|
|
|
118
118
|
return viewPort;
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
var css_248z$3 = ".ScrollContainer-module_ScrollContainer__As0vK {\n height: 100%;\n width: 100%;\n z-index: 4;\n pointer-events: auto;\n}\n";
|
|
122
|
+
var styles$3 = {"ScrollContainer":"ScrollContainer-module_ScrollContainer__As0vK"};
|
|
123
|
+
styleInject(css_248z$3);
|
|
124
|
+
|
|
125
|
+
const _tmpl$$8 = /*#__PURE__*/web.template(`<div><div><div><div></div></div></div></div>`, 8);
|
|
126
|
+
const ScrollContainer = props => {
|
|
127
|
+
let scrollContentRef;
|
|
128
|
+
const [ownProps, divProps] = solidJs.splitProps(props, ["ref", "verticalDimensionName", "horizontalDimensionName", "showScrollbar"]);
|
|
129
|
+
const propsWithDefaults = solidJs.mergeProps({
|
|
130
|
+
verticalDimensionName: "vertical",
|
|
131
|
+
horizontalDimensionName: "horizontal",
|
|
132
|
+
showScrollbar: true
|
|
133
|
+
}, ownProps);
|
|
134
|
+
const verticalViewPort = solidJs.createMemo(() => useViewPortDimension(propsWithDefaults.verticalDimensionName));
|
|
135
|
+
const horizontalViewPort = solidJs.createMemo(() => useViewPortDimension(propsWithDefaults.horizontalDimensionName));
|
|
136
|
+
const handleScroll = event => {
|
|
137
|
+
event.preventDefault();
|
|
138
|
+
if (didUpdateScroll) {
|
|
139
|
+
didUpdateScroll = false;
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
143
|
+
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
144
|
+
const height = verticalViewPort().pixelSize;
|
|
145
|
+
const width = horizontalViewPort().pixelSize;
|
|
146
|
+
const {
|
|
147
|
+
scrollTop,
|
|
148
|
+
scrollLeft,
|
|
149
|
+
scrollWidth,
|
|
150
|
+
scrollHeight
|
|
151
|
+
} = event.currentTarget;
|
|
152
|
+
const scrollTopAmount = scrollTop / (scrollHeight - height);
|
|
153
|
+
const scrollLeftAmount = scrollLeft / (scrollWidth - width);
|
|
154
|
+
verticalViewPort().onPositionChange?.(maxVerticalPosition * scrollTopAmount);
|
|
155
|
+
horizontalViewPort().onPositionChange?.(maxPosition * scrollLeftAmount);
|
|
156
|
+
};
|
|
157
|
+
const handleWheel = event => {
|
|
158
|
+
if (event.altKey) {
|
|
159
|
+
event.preventDefault();
|
|
160
|
+
if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) {
|
|
161
|
+
horizontalViewPort()?.onZoomChange?.(horizontalViewPort().zoom * (1 + event.deltaX / horizontalViewPort().pixelSize));
|
|
162
|
+
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
163
|
+
horizontalViewPort()?.onPositionChange?.(Math.min(maxPosition, horizontalViewPort()?.position));
|
|
164
|
+
} else {
|
|
165
|
+
verticalViewPort()?.onZoomChange?.(verticalViewPort().zoom * (1 + event.deltaY / verticalViewPort().pixelSize));
|
|
166
|
+
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
167
|
+
verticalViewPort()?.onPositionChange?.(Math.min(maxVerticalPosition, verticalViewPort()?.position));
|
|
168
|
+
}
|
|
169
|
+
} else if (!props.showScrollbar) {
|
|
170
|
+
event.preventDefault();
|
|
171
|
+
event.currentTarget.scrollLeft += event.deltaX;
|
|
172
|
+
event.currentTarget.scrollTop += event.deltaY;
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
let didUpdateScroll = false;
|
|
176
|
+
solidJs.createEffect(() => {
|
|
177
|
+
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
178
|
+
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
179
|
+
const scrollTopAmount = maxVerticalPosition > 0 ? verticalViewPort().position / maxVerticalPosition : 0;
|
|
180
|
+
const scrollLeftAmount = maxPosition > 0 ? horizontalViewPort().position / maxPosition : 0;
|
|
181
|
+
const height = verticalViewPort().pixelSize;
|
|
182
|
+
const width = horizontalViewPort().pixelSize;
|
|
183
|
+
if (!scrollContentRef?.parentElement) return;
|
|
184
|
+
const scrollDivHeight = verticalViewPort().zoom * verticalViewPort().pixelSize;
|
|
185
|
+
const scrollTop = scrollTopAmount * (scrollDivHeight - height);
|
|
186
|
+
const scrollDivWidth = horizontalViewPort().zoom * horizontalViewPort().pixelSize;
|
|
187
|
+
const scrollLeft = scrollLeftAmount * (scrollDivWidth - width);
|
|
188
|
+
didUpdateScroll = true;
|
|
189
|
+
scrollContentRef.style.height = `${scrollDivHeight}px`;
|
|
190
|
+
scrollContentRef.style.width = `${scrollDivWidth}px`;
|
|
191
|
+
scrollContentRef.parentElement.scrollTo({
|
|
192
|
+
left: scrollLeft,
|
|
193
|
+
top: scrollTop
|
|
194
|
+
});
|
|
195
|
+
});
|
|
124
196
|
return (() => {
|
|
125
|
-
const _el$ = _tmpl$$8.cloneNode(true)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
_v$3 = key().number % 12,
|
|
146
|
-
_v$4 = `${virtualDimensions().offset}px`,
|
|
147
|
-
_v$5 = `${virtualDimensions().size}px`;
|
|
148
|
-
_p$._v$ = web.classList(_el$2, _v$, _p$._v$);
|
|
149
|
-
_v$2 !== _p$._v$2 && web.setAttribute(_el$2, "title", _p$._v$2 = _v$2);
|
|
150
|
-
_v$3 !== _p$._v$3 && web.setAttribute(_el$2, "data-index", _p$._v$3 = _v$3);
|
|
151
|
-
_v$4 !== _p$._v$4 && _el$2.style.setProperty("top", _p$._v$4 = _v$4);
|
|
152
|
-
_v$5 !== _p$._v$5 && _el$2.style.setProperty("height", _p$._v$5 = _v$5);
|
|
153
|
-
return _p$;
|
|
154
|
-
}, {
|
|
155
|
-
_v$: undefined,
|
|
156
|
-
_v$2: undefined,
|
|
157
|
-
_v$3: undefined,
|
|
158
|
-
_v$4: undefined,
|
|
159
|
-
_v$5: undefined
|
|
160
|
-
});
|
|
161
|
-
return _el$2;
|
|
162
|
-
}
|
|
163
|
-
});
|
|
197
|
+
const _el$ = _tmpl$$8.cloneNode(true),
|
|
198
|
+
_el$2 = _el$.firstChild,
|
|
199
|
+
_el$3 = _el$2.firstChild,
|
|
200
|
+
_el$4 = _el$3.firstChild;
|
|
201
|
+
_el$.addEventListener("wheel", handleWheel);
|
|
202
|
+
_el$.addEventListener("scroll", handleScroll);
|
|
203
|
+
const _ref$ = props.ref;
|
|
204
|
+
typeof _ref$ === "function" ? web.use(_ref$, _el$) : props.ref = _el$;
|
|
205
|
+
web.spread(_el$, web.mergeProps({
|
|
206
|
+
get style() {
|
|
207
|
+
return {
|
|
208
|
+
overflow: propsWithDefaults.showScrollbar ? "scroll" : "hidden",
|
|
209
|
+
...(typeof divProps.style === "object" && divProps.style)
|
|
210
|
+
};
|
|
211
|
+
},
|
|
212
|
+
get classList() {
|
|
213
|
+
return {
|
|
214
|
+
[styles$3.ScrollContainer]: true,
|
|
215
|
+
...divProps.classList
|
|
216
|
+
};
|
|
164
217
|
}
|
|
165
|
-
}));
|
|
166
|
-
|
|
218
|
+
}, divProps), false, true);
|
|
219
|
+
const _ref$2 = scrollContentRef;
|
|
220
|
+
typeof _ref$2 === "function" ? web.use(_ref$2, _el$2) : scrollContentRef = _el$2;
|
|
221
|
+
_el$3.style.setProperty("top", "0");
|
|
222
|
+
_el$3.style.setProperty("left", "0");
|
|
223
|
+
_el$3.style.setProperty("position", "sticky");
|
|
224
|
+
_el$3.style.setProperty("display", "flex");
|
|
225
|
+
_el$4.style.setProperty("position", "relative");
|
|
226
|
+
web.insert(_el$4, () => props.children);
|
|
227
|
+
web.effect(_p$ => {
|
|
228
|
+
const _v$ = `${verticalViewPort().pixelSize}px`,
|
|
229
|
+
_v$2 = `${horizontalViewPort().pixelSize}px`,
|
|
230
|
+
_v$3 = `${verticalViewPort().pixelSize}px`,
|
|
231
|
+
_v$4 = `${horizontalViewPort().pixelSize}px`;
|
|
232
|
+
_v$ !== _p$._v$ && _el$3.style.setProperty("height", _p$._v$ = _v$);
|
|
233
|
+
_v$2 !== _p$._v$2 && _el$3.style.setProperty("width", _p$._v$2 = _v$2);
|
|
234
|
+
_v$3 !== _p$._v$3 && _el$4.style.setProperty("height", _p$._v$3 = _v$3);
|
|
235
|
+
_v$4 !== _p$._v$4 && _el$4.style.setProperty("width", _p$._v$4 = _v$4);
|
|
236
|
+
return _p$;
|
|
237
|
+
}, {
|
|
238
|
+
_v$: undefined,
|
|
239
|
+
_v$2: undefined,
|
|
240
|
+
_v$3: undefined,
|
|
241
|
+
_v$4: undefined
|
|
242
|
+
});
|
|
167
243
|
return _el$;
|
|
168
244
|
})();
|
|
169
245
|
};
|
|
246
|
+
|
|
247
|
+
const _tmpl$$7 = /*#__PURE__*/web.template(`<div></div>`, 2);
|
|
248
|
+
const PianoRollKeys = () => {
|
|
249
|
+
const viewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
|
|
250
|
+
const [isMouseDown, setIsMouseDown] = solidJs.createSignal(false);
|
|
251
|
+
const context = usePianoRollContext();
|
|
252
|
+
const handleMouseUp = () => {
|
|
253
|
+
setIsMouseDown(false);
|
|
254
|
+
};
|
|
255
|
+
solidJs.createEffect(() => {
|
|
256
|
+
if (isMouseDown()) {
|
|
257
|
+
window.addEventListener("mouseup", handleMouseUp);
|
|
258
|
+
} else {
|
|
259
|
+
window.removeEventListener("mouseup", handleMouseUp);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
return web.createComponent(ScrollContainer, {
|
|
263
|
+
get classList() {
|
|
264
|
+
return {
|
|
265
|
+
[styles$4.PianoRollKeys]: true
|
|
266
|
+
};
|
|
267
|
+
},
|
|
268
|
+
showScrollbar: false,
|
|
269
|
+
get children() {
|
|
270
|
+
return web.createComponent(solidJs.Index, {
|
|
271
|
+
each: keys,
|
|
272
|
+
children: key => {
|
|
273
|
+
const isDown = solidJs.createMemo(() => context.pressedKeys.includes(key().number));
|
|
274
|
+
const handleKeyDown = () => {
|
|
275
|
+
context.onPressedKeysChange?.([...context.pressedKeys, key().number]);
|
|
276
|
+
};
|
|
277
|
+
const handleKeyUp = () => {
|
|
278
|
+
context.onPressedKeysChange?.([...context.pressedKeys].filter(number => number !== key().number));
|
|
279
|
+
};
|
|
280
|
+
const virtualDimensions = solidJs.createMemo(() => viewPort().calculatePixelDimensions(127 - key().number, 1));
|
|
281
|
+
const previousIsBlack = blackKeys.includes((key().number - 1) % 12);
|
|
282
|
+
const nextIsBlack = blackKeys.includes((key().number + 1) % 12);
|
|
283
|
+
return web.createComponent(solidJs.Show, {
|
|
284
|
+
get when() {
|
|
285
|
+
return virtualDimensions().size > 0;
|
|
286
|
+
},
|
|
287
|
+
get children() {
|
|
288
|
+
const _el$ = _tmpl$$7.cloneNode(true);
|
|
289
|
+
_el$.addEventListener("mouseleave", () => {
|
|
290
|
+
if (isMouseDown()) {
|
|
291
|
+
handleKeyUp();
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
_el$.addEventListener("mouseenter", () => {
|
|
295
|
+
if (isMouseDown()) {
|
|
296
|
+
handleKeyDown();
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
_el$.$$mouseup = () => {
|
|
300
|
+
handleKeyUp();
|
|
301
|
+
};
|
|
302
|
+
_el$.$$mousedown = () => {
|
|
303
|
+
setIsMouseDown(true);
|
|
304
|
+
handleKeyDown();
|
|
305
|
+
};
|
|
306
|
+
web.insert(_el$, web.createComponent(solidJs.Show, {
|
|
307
|
+
get when() {
|
|
308
|
+
return key().isBlack && false;
|
|
309
|
+
},
|
|
310
|
+
get children() {
|
|
311
|
+
const _el$2 = _tmpl$$7.cloneNode(true);
|
|
312
|
+
web.effect(_p$ => {
|
|
313
|
+
const _v$ = styles$4["black-separator"],
|
|
314
|
+
_v$2 = `${virtualDimensions().offset}px`,
|
|
315
|
+
_v$3 = `${virtualDimensions().size / 2 - 0.25}px`;
|
|
316
|
+
_v$ !== _p$._v$ && web.className(_el$2, _p$._v$ = _v$);
|
|
317
|
+
_v$2 !== _p$._v$2 && _el$2.style.setProperty("top", _p$._v$2 = _v$2);
|
|
318
|
+
_v$3 !== _p$._v$3 && _el$2.style.setProperty("height", _p$._v$3 = _v$3);
|
|
319
|
+
return _p$;
|
|
320
|
+
}, {
|
|
321
|
+
_v$: undefined,
|
|
322
|
+
_v$2: undefined,
|
|
323
|
+
_v$3: undefined
|
|
324
|
+
});
|
|
325
|
+
return _el$2;
|
|
326
|
+
}
|
|
327
|
+
}));
|
|
328
|
+
web.effect(_p$ => {
|
|
329
|
+
const _v$4 = {
|
|
330
|
+
[styles$4["Key"]]: true,
|
|
331
|
+
[styles$4["black"]]: key().isBlack,
|
|
332
|
+
[styles$4["white"]]: !key().isBlack,
|
|
333
|
+
[styles$4["down"]]: isDown()
|
|
334
|
+
},
|
|
335
|
+
_v$5 = key().name,
|
|
336
|
+
_v$6 = key().number % 12,
|
|
337
|
+
_v$7 = `${virtualDimensions().offset - (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0)}px`,
|
|
338
|
+
_v$8 = `${virtualDimensions().size + (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0) + (!key().isBlack && previousIsBlack ? virtualDimensions().size / 2 : 0)}px`,
|
|
339
|
+
_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(", ");
|
|
340
|
+
_p$._v$4 = web.classList(_el$, _v$4, _p$._v$4);
|
|
341
|
+
_v$5 !== _p$._v$5 && web.setAttribute(_el$, "title", _p$._v$5 = _v$5);
|
|
342
|
+
_v$6 !== _p$._v$6 && web.setAttribute(_el$, "data-index", _p$._v$6 = _v$6);
|
|
343
|
+
_v$7 !== _p$._v$7 && _el$.style.setProperty("top", _p$._v$7 = _v$7);
|
|
344
|
+
_v$8 !== _p$._v$8 && _el$.style.setProperty("height", _p$._v$8 = _v$8);
|
|
345
|
+
_v$9 !== _p$._v$9 && _el$.style.setProperty("box-shadow", _p$._v$9 = _v$9);
|
|
346
|
+
return _p$;
|
|
347
|
+
}, {
|
|
348
|
+
_v$4: undefined,
|
|
349
|
+
_v$5: undefined,
|
|
350
|
+
_v$6: undefined,
|
|
351
|
+
_v$7: undefined,
|
|
352
|
+
_v$8: undefined,
|
|
353
|
+
_v$9: undefined
|
|
354
|
+
});
|
|
355
|
+
return _el$;
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
};
|
|
170
363
|
const blackKeys = [1, 3, 6, 8, 10];
|
|
171
364
|
const keyNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
172
365
|
const keys = Array.from({
|
|
@@ -176,15 +369,16 @@ const keys = Array.from({
|
|
|
176
369
|
name: `${keyNames[index % 12]} ${Math.floor(index / 12) - 2}`,
|
|
177
370
|
isBlack: blackKeys.includes(index % 12)
|
|
178
371
|
}));
|
|
372
|
+
web.delegateEvents(["mousedown", "mouseup"]);
|
|
179
373
|
|
|
180
374
|
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}";
|
|
181
375
|
var styles$2 = {"PianoRollNotes":"PianoRollNotes-module_PianoRollNotes__6pF-y","Note":"PianoRollNotes-module_Note__-jxLb","trimStart":"PianoRollNotes-module_trimStart__vuBlj","trimEnd":"PianoRollNotes-module_trimEnd__zPdjr"};
|
|
182
376
|
styleInject(css_248z$2);
|
|
183
377
|
|
|
184
|
-
const _tmpl$$
|
|
378
|
+
const _tmpl$$6 = /*#__PURE__*/web.template(`<div></div>`, 2);
|
|
185
379
|
const PianoRollNotes = props => {
|
|
186
380
|
const context = usePianoRollContext();
|
|
187
|
-
const verticalViewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
|
|
381
|
+
const verticalViewPort = solidJs.createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
|
|
188
382
|
const horizontalViewPort = solidJs.createMemo(() => useViewPortDimension("horizontal"));
|
|
189
383
|
const gridDivisionTicks = solidJs.createMemo(() => context.ppq * 4 / context.gridDivision);
|
|
190
384
|
const snapValueToGridIfEnabled = (value, altKey) => context.snapToGrid && !altKey ? Math.round(value / gridDivisionTicks()) * gridDivisionTicks() : value;
|
|
@@ -192,7 +386,7 @@ const PianoRollNotes = props => {
|
|
|
192
386
|
const position = horizontalViewPort().calculatePosition(event.clientX);
|
|
193
387
|
const existingNote = currentNote();
|
|
194
388
|
const midi = context.mode === "keys" ? 127 - Math.floor(verticalViewPort().calculatePosition(event.clientY)) : existingNote?.midi ?? 60;
|
|
195
|
-
const targetTrackIndex = context.mode === "tracks" ? Math.floor(verticalViewPort().calculatePosition(event.clientY)) : context.selectedTrackIndex ?? 0;
|
|
389
|
+
const targetTrackIndex = context.mode === "tracks" ? clamp(Math.floor(verticalViewPort().calculatePosition(event.clientY)), 0, context.tracks.length - 1) : context.selectedTrackIndex ?? 0;
|
|
196
390
|
const eventPositionTicks = Math.floor(position / gridDivisionTicks()) * gridDivisionTicks();
|
|
197
391
|
const velocity = 127;
|
|
198
392
|
const ticks = existingNote?.ticks ?? eventPositionTicks;
|
|
@@ -220,7 +414,7 @@ const PianoRollNotes = props => {
|
|
|
220
414
|
return noteDragMode ? [styles$2.Note, styles$2[noteDragMode]] : [styles$2.Note];
|
|
221
415
|
};
|
|
222
416
|
return (() => {
|
|
223
|
-
const _el$ = _tmpl$$
|
|
417
|
+
const _el$ = _tmpl$$6.cloneNode(true);
|
|
224
418
|
_el$.$$click = event => {
|
|
225
419
|
if (currentNote()) {
|
|
226
420
|
setCurrentNoteIndex(-1);
|
|
@@ -278,7 +472,7 @@ const PianoRollNotes = props => {
|
|
|
278
472
|
return web.memo(() => !!verticalViewPort().isVisible(verticalVirtualDimensions()))() && horizontalViewPort().isVisible(horizontalDimensions());
|
|
279
473
|
},
|
|
280
474
|
get children() {
|
|
281
|
-
const _el$2 = _tmpl$$
|
|
475
|
+
const _el$2 = _tmpl$$6.cloneNode(true);
|
|
282
476
|
_el$2.$$mousedown = event => {
|
|
283
477
|
event.stopPropagation();
|
|
284
478
|
setIsDragging(true);
|
|
@@ -307,7 +501,7 @@ const PianoRollNotes = props => {
|
|
|
307
501
|
};
|
|
308
502
|
const previousTrackIndex = currentNoteTrackIndex();
|
|
309
503
|
const previousNoteIndex = currentNoteIndex();
|
|
310
|
-
const targetTrackIndex = context.mode === "tracks" ? Math.floor(verticalViewPort().calculatePosition(mouseMoveEvent.clientY)) : previousTrackIndex;
|
|
504
|
+
const targetTrackIndex = context.mode === "tracks" ? clamp(Math.floor(verticalViewPort().calculatePosition(mouseMoveEvent.clientY)), 0, context.tracks.length - 1) : previousTrackIndex;
|
|
311
505
|
if (targetTrackIndex === previousTrackIndex) {
|
|
312
506
|
context.onNoteChange?.(previousTrackIndex, previousNoteIndex, updatedNote);
|
|
313
507
|
} else {
|
|
@@ -381,109 +575,6 @@ const PianoRollNotes = props => {
|
|
|
381
575
|
};
|
|
382
576
|
web.delegateEvents(["mousedown", "mousemove", "mouseup", "dblclick", "click"]);
|
|
383
577
|
|
|
384
|
-
const _tmpl$$6 = /*#__PURE__*/web.template(`<div class="PianoRoll-Scroller"><div><div><div></div></div></div></div>`, 8);
|
|
385
|
-
const ScrollContainer = props => {
|
|
386
|
-
let scrollContentRef;
|
|
387
|
-
const verticalViewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
|
|
388
|
-
const horizontalViewPort = solidJs.createMemo(() => useViewPortDimension("horizontal"));
|
|
389
|
-
const handleScroll = event => {
|
|
390
|
-
event.preventDefault();
|
|
391
|
-
if (didUpdateScroll) {
|
|
392
|
-
didUpdateScroll = false;
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
396
|
-
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
397
|
-
const height = verticalViewPort().pixelSize;
|
|
398
|
-
const width = horizontalViewPort().pixelSize;
|
|
399
|
-
const {
|
|
400
|
-
scrollTop,
|
|
401
|
-
scrollLeft,
|
|
402
|
-
scrollWidth,
|
|
403
|
-
scrollHeight
|
|
404
|
-
} = event.currentTarget;
|
|
405
|
-
const scrollTopAmount = scrollTop / (scrollHeight - height);
|
|
406
|
-
const scrollLeftAmount = scrollLeft / (scrollWidth - width);
|
|
407
|
-
verticalViewPort().onPositionChange?.(maxVerticalPosition * scrollTopAmount);
|
|
408
|
-
horizontalViewPort().onPositionChange?.(maxPosition * scrollLeftAmount);
|
|
409
|
-
};
|
|
410
|
-
const handleWheel = event => {
|
|
411
|
-
if (event.altKey) {
|
|
412
|
-
event.preventDefault();
|
|
413
|
-
if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) {
|
|
414
|
-
horizontalViewPort()?.onZoomChange?.(horizontalViewPort().zoom * (1 + event.deltaX / horizontalViewPort().pixelSize));
|
|
415
|
-
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
416
|
-
horizontalViewPort()?.onPositionChange?.(Math.min(maxPosition, horizontalViewPort()?.position));
|
|
417
|
-
} else {
|
|
418
|
-
verticalViewPort()?.onZoomChange?.(verticalViewPort().zoom * (1 + event.deltaY / verticalViewPort().pixelSize));
|
|
419
|
-
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
420
|
-
verticalViewPort()?.onPositionChange?.(Math.min(maxVerticalPosition, verticalViewPort()?.position));
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
};
|
|
424
|
-
let didUpdateScroll = false;
|
|
425
|
-
solidJs.createEffect(() => {
|
|
426
|
-
const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
|
|
427
|
-
const maxPosition = horizontalViewPort().calculateMaxPosition();
|
|
428
|
-
const scrollTopAmount = maxVerticalPosition > 0 ? verticalViewPort().position / maxVerticalPosition : 0;
|
|
429
|
-
const scrollLeftAmount = maxPosition > 0 ? horizontalViewPort().position / maxPosition : 0;
|
|
430
|
-
const height = verticalViewPort().pixelSize;
|
|
431
|
-
const width = horizontalViewPort().pixelSize;
|
|
432
|
-
if (!scrollContentRef?.parentElement) return;
|
|
433
|
-
const scrollDivHeight = verticalViewPort().zoom * verticalViewPort().pixelSize;
|
|
434
|
-
const scrollTop = scrollTopAmount * (scrollDivHeight - height);
|
|
435
|
-
const scrollDivWidth = horizontalViewPort().zoom * horizontalViewPort().pixelSize;
|
|
436
|
-
const scrollLeft = scrollLeftAmount * (scrollDivWidth - width);
|
|
437
|
-
didUpdateScroll = true;
|
|
438
|
-
scrollContentRef.style.height = `${scrollDivHeight}px`;
|
|
439
|
-
scrollContentRef.style.width = `${scrollDivWidth}px`;
|
|
440
|
-
scrollContentRef.parentElement.scrollTo({
|
|
441
|
-
left: scrollLeft,
|
|
442
|
-
top: scrollTop
|
|
443
|
-
});
|
|
444
|
-
});
|
|
445
|
-
return (() => {
|
|
446
|
-
const _el$ = _tmpl$$6.cloneNode(true),
|
|
447
|
-
_el$2 = _el$.firstChild,
|
|
448
|
-
_el$3 = _el$2.firstChild,
|
|
449
|
-
_el$4 = _el$3.firstChild;
|
|
450
|
-
_el$.addEventListener("wheel", handleWheel);
|
|
451
|
-
_el$.addEventListener("scroll", handleScroll);
|
|
452
|
-
const _ref$ = props.ref;
|
|
453
|
-
typeof _ref$ === "function" ? web.use(_ref$, _el$) : props.ref = _el$;
|
|
454
|
-
_el$.style.setProperty("height", "100%");
|
|
455
|
-
_el$.style.setProperty("width", "100%");
|
|
456
|
-
_el$.style.setProperty("z-index", "4");
|
|
457
|
-
_el$.style.setProperty("overflow", "scroll");
|
|
458
|
-
_el$.style.setProperty("pointer-events", "auto");
|
|
459
|
-
const _ref$2 = scrollContentRef;
|
|
460
|
-
typeof _ref$2 === "function" ? web.use(_ref$2, _el$2) : scrollContentRef = _el$2;
|
|
461
|
-
_el$3.style.setProperty("top", "0");
|
|
462
|
-
_el$3.style.setProperty("left", "0");
|
|
463
|
-
_el$3.style.setProperty("position", "sticky");
|
|
464
|
-
_el$3.style.setProperty("display", "flex");
|
|
465
|
-
_el$4.style.setProperty("position", "relative");
|
|
466
|
-
web.insert(_el$4, () => props.children);
|
|
467
|
-
web.effect(_p$ => {
|
|
468
|
-
const _v$ = `${verticalViewPort().pixelSize}px`,
|
|
469
|
-
_v$2 = `${horizontalViewPort().pixelSize}px`,
|
|
470
|
-
_v$3 = `${verticalViewPort().pixelSize}px`,
|
|
471
|
-
_v$4 = `${horizontalViewPort().pixelSize}px`;
|
|
472
|
-
_v$ !== _p$._v$ && _el$3.style.setProperty("height", _p$._v$ = _v$);
|
|
473
|
-
_v$2 !== _p$._v$2 && _el$3.style.setProperty("width", _p$._v$2 = _v$2);
|
|
474
|
-
_v$3 !== _p$._v$3 && _el$4.style.setProperty("height", _p$._v$3 = _v$3);
|
|
475
|
-
_v$4 !== _p$._v$4 && _el$4.style.setProperty("width", _p$._v$4 = _v$4);
|
|
476
|
-
return _p$;
|
|
477
|
-
}, {
|
|
478
|
-
_v$: undefined,
|
|
479
|
-
_v$2: undefined,
|
|
480
|
-
_v$3: undefined,
|
|
481
|
-
_v$4: undefined
|
|
482
|
-
});
|
|
483
|
-
return _el$;
|
|
484
|
-
})();
|
|
485
|
-
};
|
|
486
|
-
|
|
487
578
|
var css_248z$1 = ".PianoRollGrid-module_PianoRollGrid__tG119 {\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.PianoRollGrid-module_PianoRollGrid-Row__nRMCs {\n position: absolute;\n border-style: solid;\n border-color: gray;\n}\n\n.PianoRollGrid-module_PianoRollGrid-Time__jLz3E {\n position: absolute;\n box-sizing: border-box;\n top: 0px;\n height: 100%;\n border-left-style: solid;\n border-left-width: 0.5px;\n}\n";
|
|
488
579
|
var styles$1 = {"PianoRollGrid":"PianoRollGrid-module_PianoRollGrid__tG119","PianoRollGrid-Row":"PianoRollGrid-module_PianoRollGrid-Row__nRMCs","PianoRollGrid-Time":"PianoRollGrid-module_PianoRollGrid-Time__jLz3E"};
|
|
489
580
|
styleInject(css_248z$1);
|
|
@@ -491,7 +582,7 @@ styleInject(css_248z$1);
|
|
|
491
582
|
const _tmpl$$5 = /*#__PURE__*/web.template(`<div></div>`, 2);
|
|
492
583
|
const PianoRollGrid = () => {
|
|
493
584
|
const context = usePianoRollContext();
|
|
494
|
-
const verticalViewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
|
|
585
|
+
const verticalViewPort = solidJs.createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
|
|
495
586
|
const horizontalViewPort = solidJs.createMemo(() => useViewPortDimension("horizontal"));
|
|
496
587
|
const measureTicks = solidJs.createMemo(() => context.ppq * 4);
|
|
497
588
|
const selectedGridDivisorTicks = solidJs.createMemo(() => measureTicks() / context.gridDivision);
|
|
@@ -674,14 +765,14 @@ function useBoundingClientRect(containerRef) {
|
|
|
674
765
|
|
|
675
766
|
const _tmpl$$4 = /*#__PURE__*/web.template(`<input min="1" max="11" step="0.01">`, 1);
|
|
676
767
|
const VerticalZoomControl = props => {
|
|
677
|
-
const
|
|
768
|
+
const dimension = solidJs.createMemo(() => useViewPortDimension(props.dimensionName ?? "vertical"));
|
|
678
769
|
return (() => {
|
|
679
770
|
const _el$ = _tmpl$$4.cloneNode(true);
|
|
680
771
|
web.spread(_el$, web.mergeProps(props, {
|
|
681
772
|
get value() {
|
|
682
|
-
return
|
|
773
|
+
return dimension().zoom;
|
|
683
774
|
},
|
|
684
|
-
"onInput": event =>
|
|
775
|
+
"onInput": event => dimension().onZoomChange?.(event.currentTarget.valueAsNumber),
|
|
685
776
|
"type": "range"
|
|
686
777
|
}, {
|
|
687
778
|
orient: "vertical"
|
|
@@ -689,6 +780,7 @@ const VerticalZoomControl = props => {
|
|
|
689
780
|
get style() {
|
|
690
781
|
return {
|
|
691
782
|
width: "16px",
|
|
783
|
+
transform: "rotate(180deg)",
|
|
692
784
|
...{
|
|
693
785
|
"writing-mode": "bt-lr" /* IE */,
|
|
694
786
|
"-webkit-appearance": "slider-vertical" /* WebKit */
|
|
@@ -702,14 +794,14 @@ const VerticalZoomControl = props => {
|
|
|
702
794
|
|
|
703
795
|
const _tmpl$$3 = /*#__PURE__*/web.template(`<input max="500" min="1" step="0.01">`, 1);
|
|
704
796
|
const HorizontalZoomControl = props => {
|
|
705
|
-
const
|
|
797
|
+
const dimension = solidJs.createMemo(() => useViewPortDimension(props.dimensionName ?? "horizontal"));
|
|
706
798
|
return (() => {
|
|
707
799
|
const _el$ = _tmpl$$3.cloneNode(true);
|
|
708
800
|
web.spread(_el$, web.mergeProps(props, {
|
|
709
801
|
get value() {
|
|
710
|
-
return
|
|
802
|
+
return dimension().zoom;
|
|
711
803
|
},
|
|
712
|
-
"onInput": event =>
|
|
804
|
+
"onInput": event => dimension().onZoomChange?.(event.currentTarget.valueAsNumber),
|
|
713
805
|
"type": "range",
|
|
714
806
|
get style() {
|
|
715
807
|
return {
|
|
@@ -730,7 +822,7 @@ styleInject(css_248z);
|
|
|
730
822
|
const _tmpl$$2 = /*#__PURE__*/web.template(`<div></div>`, 2),
|
|
731
823
|
_tmpl$2$1 = /*#__PURE__*/web.template(`<div> </div>`, 2);
|
|
732
824
|
const PianoRollTrackList = () => {
|
|
733
|
-
const viewPort = solidJs.createMemo(() => useViewPortDimension("
|
|
825
|
+
const viewPort = solidJs.createMemo(() => useViewPortDimension("verticalTracks"));
|
|
734
826
|
const context = usePianoRollContext();
|
|
735
827
|
return (() => {
|
|
736
828
|
const _el$ = _tmpl$$2.cloneNode(true);
|
|
@@ -739,7 +831,7 @@ const PianoRollTrackList = () => {
|
|
|
739
831
|
return context.tracks;
|
|
740
832
|
},
|
|
741
833
|
children: (track, index) => {
|
|
742
|
-
const virtualDimensions = solidJs.createMemo(() => viewPort().calculatePixelDimensions(
|
|
834
|
+
const virtualDimensions = solidJs.createMemo(() => viewPort().calculatePixelDimensions(index, 1));
|
|
743
835
|
return web.createComponent(solidJs.Show, {
|
|
744
836
|
get when() {
|
|
745
837
|
return virtualDimensions().size > 0;
|
|
@@ -783,100 +875,149 @@ const PianoRollTrackList = () => {
|
|
|
783
875
|
};
|
|
784
876
|
web.delegateEvents(["click"]);
|
|
785
877
|
|
|
786
|
-
const _tmpl$$1 = /*#__PURE__*/web.template(`<div></div>`,
|
|
787
|
-
_tmpl$2 = /*#__PURE__*/web.template(`<div
|
|
878
|
+
const _tmpl$$1 = /*#__PURE__*/web.template(`<div><div></div></div>`, 4),
|
|
879
|
+
_tmpl$2 = /*#__PURE__*/web.template(`<div></div>`, 2);
|
|
788
880
|
const PianoRoll = allProps => {
|
|
789
|
-
const
|
|
881
|
+
const propsWithDefaults = solidJs.mergeProps({
|
|
882
|
+
showAllTracks: false
|
|
883
|
+
}, allProps);
|
|
884
|
+
const [context, divProps] = splitContextProps(propsWithDefaults);
|
|
790
885
|
const [scrollerRef, setScrollerRef] = solidJs.createSignal();
|
|
886
|
+
const [trackScrollerRef, setTrackScrollerRef] = solidJs.createSignal();
|
|
791
887
|
const clientRect = useBoundingClientRect(scrollerRef);
|
|
888
|
+
const trackClientRef = useBoundingClientRect(trackScrollerRef);
|
|
792
889
|
const zoomFactor = 500;
|
|
793
890
|
const minZoom = solidJs.createMemo(() => 1 / (zoomFactor / clientRect().width));
|
|
794
891
|
const maxZoom = solidJs.createMemo(() => 500 * (zoomFactor / clientRect().width));
|
|
795
892
|
const minVerticalZoom = solidJs.createMemo(() => 1 / (zoomFactor / clientRect().height));
|
|
796
893
|
const maxVerticalZoom = solidJs.createMemo(() => 10 * (zoomFactor / clientRect().height));
|
|
894
|
+
const minVerticalTracksZoom = solidJs.createMemo(() => 0.8 / (zoomFactor / trackClientRef().height));
|
|
895
|
+
const maxVerticalTracksZoom = solidJs.createMemo(() => 3 * (zoomFactor / trackClientRef().height));
|
|
797
896
|
solidJs.createEffect(isInitial => {
|
|
798
897
|
if (isInitial) return false;
|
|
799
|
-
if (
|
|
800
|
-
|
|
898
|
+
if (context.mode === "tracks") {
|
|
899
|
+
context.onVerticalPositionChange?.(0);
|
|
801
900
|
}
|
|
802
901
|
}, true);
|
|
803
902
|
return web.createComponent(PianoRollContextProvider, {
|
|
804
|
-
value:
|
|
903
|
+
value: context,
|
|
805
904
|
get children() {
|
|
806
|
-
const _el$ = _tmpl$2.cloneNode(true)
|
|
807
|
-
_el$2 = _el$.firstChild;
|
|
905
|
+
const _el$ = _tmpl$2.cloneNode(true);
|
|
808
906
|
web.spread(_el$, web.mergeProps(divProps, {
|
|
809
907
|
get ["class"]() {
|
|
810
|
-
return styles$
|
|
908
|
+
return styles$5.PianoRoll;
|
|
811
909
|
}
|
|
812
910
|
}), false, true);
|
|
813
|
-
web.insert(_el
|
|
911
|
+
web.insert(_el$, web.createComponent(ScrollZoomViewPort, {
|
|
814
912
|
dimensions: {
|
|
815
913
|
horizontal: () => ({
|
|
816
914
|
pixelOffset: clientRect().left,
|
|
817
915
|
pixelSize: clientRect().width,
|
|
818
|
-
position:
|
|
819
|
-
range:
|
|
820
|
-
zoom:
|
|
821
|
-
onPositionChange:
|
|
822
|
-
onZoomChange: zoom =>
|
|
916
|
+
position: context.position,
|
|
917
|
+
range: context.duration,
|
|
918
|
+
zoom: context.zoom * (zoomFactor / clientRect().width),
|
|
919
|
+
onPositionChange: context.onPositionChange,
|
|
920
|
+
onZoomChange: zoom => context.onZoomChange?.(clamp(zoom / (zoomFactor / clientRect().width), minZoom(), maxZoom()))
|
|
823
921
|
}),
|
|
824
922
|
vertical: () => ({
|
|
825
923
|
pixelOffset: clientRect().top,
|
|
826
924
|
pixelSize: clientRect().height,
|
|
827
|
-
position:
|
|
828
|
-
range:
|
|
829
|
-
zoom:
|
|
830
|
-
onPositionChange:
|
|
831
|
-
onZoomChange: verticalZoom =>
|
|
925
|
+
position: context.verticalPosition,
|
|
926
|
+
range: 128,
|
|
927
|
+
zoom: context.verticalZoom * (zoomFactor / clientRect().height),
|
|
928
|
+
onPositionChange: context.onVerticalPositionChange,
|
|
929
|
+
onZoomChange: verticalZoom => context.onVerticalZoomChange?.(clamp(verticalZoom / (zoomFactor / clientRect().height), minVerticalZoom(), maxVerticalZoom()))
|
|
930
|
+
}),
|
|
931
|
+
horizontalTracks: () => ({
|
|
932
|
+
pixelOffset: clientRect().left,
|
|
933
|
+
pixelSize: clientRect().width,
|
|
934
|
+
position: 0,
|
|
935
|
+
range: 1,
|
|
936
|
+
zoom: 1
|
|
937
|
+
}),
|
|
938
|
+
verticalTracks: () => ({
|
|
939
|
+
pixelOffset: trackClientRef().top,
|
|
940
|
+
pixelSize: trackClientRef().height,
|
|
941
|
+
position: context.verticalTrackPosition,
|
|
942
|
+
range: context.tracks.length,
|
|
943
|
+
zoom: context.verticalTrackZoom * (zoomFactor / trackClientRef().height),
|
|
944
|
+
onPositionChange: context.onVerticalTrackPositionChange,
|
|
945
|
+
onZoomChange: verticalTrackZoom => context.onVerticalTrackZoomChange?.(clamp(verticalTrackZoom / (zoomFactor / trackClientRef().height), minVerticalTracksZoom(), maxVerticalTracksZoom()))
|
|
832
946
|
})
|
|
833
947
|
},
|
|
834
948
|
get children() {
|
|
835
949
|
return [(() => {
|
|
836
|
-
const _el$
|
|
950
|
+
const _el$2 = _tmpl$$1.cloneNode(true),
|
|
951
|
+
_el$3 = _el$2.firstChild;
|
|
952
|
+
web.insert(_el$2, web.createComponent(VerticalZoomControl, {
|
|
953
|
+
get min() {
|
|
954
|
+
return minVerticalTracksZoom();
|
|
955
|
+
},
|
|
956
|
+
get max() {
|
|
957
|
+
return maxVerticalTracksZoom();
|
|
958
|
+
},
|
|
959
|
+
dimensionName: "verticalTracks"
|
|
960
|
+
}), _el$3);
|
|
837
961
|
_el$3.style.setProperty("display", "flex");
|
|
838
962
|
_el$3.style.setProperty("width", "20%");
|
|
839
963
|
web.insert(_el$3, web.createComponent(solidJs.Show, {
|
|
840
964
|
get when() {
|
|
841
|
-
return
|
|
965
|
+
return context.showTrackList;
|
|
842
966
|
},
|
|
843
967
|
get children() {
|
|
844
|
-
return web.createComponent(
|
|
968
|
+
return web.createComponent(ScrollContainer, {
|
|
969
|
+
ref: setTrackScrollerRef,
|
|
970
|
+
horizontalDimensionName: "horizontalTracks",
|
|
971
|
+
verticalDimensionName: "verticalTracks",
|
|
972
|
+
get showScrollbar() {
|
|
973
|
+
return context.mode === "keys";
|
|
974
|
+
},
|
|
975
|
+
get children() {
|
|
976
|
+
return web.createComponent(PianoRollTrackList, {});
|
|
977
|
+
}
|
|
978
|
+
});
|
|
845
979
|
}
|
|
846
980
|
}), null);
|
|
847
981
|
web.insert(_el$3, web.createComponent(solidJs.Show, {
|
|
848
982
|
get when() {
|
|
849
|
-
return
|
|
983
|
+
return context.mode === "keys";
|
|
850
984
|
},
|
|
851
985
|
get children() {
|
|
852
986
|
return web.createComponent(PianoRollKeys, {});
|
|
853
987
|
}
|
|
854
988
|
}), null);
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
989
|
+
web.insert(_el$2, web.createComponent(ScrollContainer, {
|
|
990
|
+
ref: setScrollerRef,
|
|
991
|
+
get verticalDimensionName() {
|
|
992
|
+
return context.mode === "keys" ? "vertical" : "verticalTracks";
|
|
993
|
+
},
|
|
994
|
+
get children() {
|
|
995
|
+
return [web.memo(() => allProps.children), web.createComponent(PianoRollGrid, {}), web.createComponent(PianoRollNotes, {})];
|
|
996
|
+
}
|
|
997
|
+
}), null);
|
|
998
|
+
web.insert(_el$2, web.createComponent(VerticalZoomControl, {
|
|
999
|
+
get min() {
|
|
1000
|
+
return minVerticalZoom();
|
|
1001
|
+
},
|
|
1002
|
+
get max() {
|
|
1003
|
+
return maxVerticalZoom();
|
|
1004
|
+
},
|
|
1005
|
+
get disabled() {
|
|
1006
|
+
return context.mode !== "keys";
|
|
1007
|
+
}
|
|
1008
|
+
}), null);
|
|
1009
|
+
web.effect(() => web.className(_el$2, styles$5.PianoRollContainer));
|
|
1010
|
+
return _el$2;
|
|
1011
|
+
})(), web.createComponent(HorizontalZoomControl, {
|
|
862
1012
|
get min() {
|
|
863
|
-
return
|
|
1013
|
+
return minZoom();
|
|
864
1014
|
},
|
|
865
1015
|
get max() {
|
|
866
|
-
return
|
|
1016
|
+
return maxZoom();
|
|
867
1017
|
}
|
|
868
1018
|
})];
|
|
869
1019
|
}
|
|
870
1020
|
}));
|
|
871
|
-
web.insert(_el$, web.createComponent(HorizontalZoomControl, {
|
|
872
|
-
get min() {
|
|
873
|
-
return minZoom();
|
|
874
|
-
},
|
|
875
|
-
get max() {
|
|
876
|
-
return maxZoom();
|
|
877
|
-
}
|
|
878
|
-
}), null);
|
|
879
|
-
web.effect(() => web.className(_el$2, styles$4.PianoRollContainer));
|
|
880
1021
|
return _el$;
|
|
881
1022
|
}
|
|
882
1023
|
});
|
|
@@ -960,40 +1101,86 @@ const useNotes = () => {
|
|
|
960
1101
|
};
|
|
961
1102
|
};
|
|
962
1103
|
|
|
963
|
-
const
|
|
964
|
-
const [
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1104
|
+
const createPianoRollstate = defaultState => {
|
|
1105
|
+
const [state, setState] = store.createStore({
|
|
1106
|
+
ppq: 0,
|
|
1107
|
+
mode: "keys",
|
|
1108
|
+
position: 0,
|
|
1109
|
+
zoom: 10,
|
|
1110
|
+
verticalZoom: 5,
|
|
1111
|
+
verticalPosition: 44,
|
|
1112
|
+
verticalTrackZoom: 0.5,
|
|
1113
|
+
verticalTrackPosition: 0,
|
|
1114
|
+
gridDivision: 4,
|
|
1115
|
+
snapToGrid: true,
|
|
1116
|
+
duration: 0,
|
|
1117
|
+
tracks: [],
|
|
1118
|
+
selectedTrackIndex: 0,
|
|
1119
|
+
pressedKeys: [],
|
|
1120
|
+
...defaultState
|
|
1121
|
+
});
|
|
1122
|
+
const updateNotes = async (trackIndex, getNotes) => {
|
|
1123
|
+
const track = state.tracks[trackIndex];
|
|
1124
|
+
if (!track) return;
|
|
1125
|
+
const notes = track.notes;
|
|
1126
|
+
onTracksChange([...state.tracks.slice(0, trackIndex), {
|
|
1127
|
+
...track,
|
|
1128
|
+
notes: getNotes(notes)
|
|
1129
|
+
}, ...state.tracks.slice(trackIndex + 1)]);
|
|
1130
|
+
};
|
|
1131
|
+
const onNoteChange = (trackIndex, noteIndex, note) => {
|
|
1132
|
+
updateNotes(trackIndex, notes => [...notes.slice(0, noteIndex), note, ...notes.slice(noteIndex + 1)]);
|
|
1133
|
+
};
|
|
1134
|
+
const onInsertNote = (trackIndex, note) => {
|
|
1135
|
+
const track = state.tracks[trackIndex];
|
|
1136
|
+
if (!track) return -1;
|
|
1137
|
+
const notes = track.notes;
|
|
1138
|
+
const newNoteIndex = Math.max(notes.findIndex(({
|
|
1139
|
+
ticks
|
|
1140
|
+
}) => ticks > note.ticks), 0);
|
|
1141
|
+
updateNotes(trackIndex, notes => [...notes.slice(0, newNoteIndex), note, ...notes.slice(newNoteIndex)]);
|
|
1142
|
+
return newNoteIndex;
|
|
1143
|
+
};
|
|
1144
|
+
const onRemoveNote = (trackIndex, noteIndex) => {
|
|
1145
|
+
updateNotes(trackIndex, notes => [...notes.slice(0, noteIndex), ...notes.slice(noteIndex + 1)]);
|
|
1146
|
+
};
|
|
1147
|
+
const onPpqChange = ppq => setState("ppq", ppq);
|
|
1148
|
+
const onModeChange = mode => setState("mode", mode);
|
|
1149
|
+
const onPositionChange = position => setState("position", position);
|
|
1150
|
+
const onZoomChange = zoom => setState("zoom", zoom);
|
|
1151
|
+
const onVerticalZoomChange = verticalZoom => setState("verticalZoom", verticalZoom);
|
|
1152
|
+
const onVerticalPositionChange = verticalPosition => setState("verticalPosition", verticalPosition);
|
|
1153
|
+
const onVerticalTrackZoomChange = verticalTrackZoom => setState("verticalTrackZoom", verticalTrackZoom);
|
|
1154
|
+
const onVerticalTrackPositionChange = verticalTrackPosition => setState("verticalTrackPosition", verticalTrackPosition);
|
|
1155
|
+
const onGridDivisionChange = gridDivision => setState("gridDivision", gridDivision);
|
|
1156
|
+
const onSnapToGridChange = snapToGrid => setState("snapToGrid", snapToGrid);
|
|
1157
|
+
const onDurationChange = duration => setState("duration", duration);
|
|
1158
|
+
const onTracksChange = tracks => setState("tracks", tracks);
|
|
1159
|
+
const onSelectedTrackIndexChange = selectedTrackIndex => setState("selectedTrackIndex", selectedTrackIndex);
|
|
1160
|
+
const onPressedKeysChange = pressedKeys => setState("pressedKeys", pressedKeys);
|
|
1161
|
+
return solidJs.mergeProps(state, {
|
|
975
1162
|
onPpqChange,
|
|
976
|
-
|
|
1163
|
+
onModeChange,
|
|
977
1164
|
onPositionChange,
|
|
978
|
-
zoom,
|
|
979
1165
|
onZoomChange,
|
|
980
|
-
verticalPosition,
|
|
981
|
-
onVerticalPositionChange,
|
|
982
|
-
verticalZoom,
|
|
983
1166
|
onVerticalZoomChange,
|
|
984
|
-
|
|
1167
|
+
onVerticalPositionChange,
|
|
1168
|
+
onVerticalTrackZoomChange,
|
|
1169
|
+
onVerticalTrackPositionChange,
|
|
985
1170
|
onGridDivisionChange,
|
|
986
|
-
snapToGrid,
|
|
987
1171
|
onSnapToGridChange,
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
1172
|
+
onDurationChange,
|
|
1173
|
+
onTracksChange,
|
|
1174
|
+
onNoteChange,
|
|
1175
|
+
onInsertNote,
|
|
1176
|
+
onRemoveNote,
|
|
1177
|
+
onSelectedTrackIndexChange,
|
|
1178
|
+
onPressedKeysChange
|
|
1179
|
+
});
|
|
993
1180
|
};
|
|
994
1181
|
|
|
995
1182
|
exports.PianoRoll = PianoRoll;
|
|
996
1183
|
exports.PlayHead = PlayHead;
|
|
1184
|
+
exports.createPianoRollstate = createPianoRollstate;
|
|
997
1185
|
exports.useNotes = useNotes;
|
|
998
|
-
exports.usePianoRoll = usePianoRoll;
|
|
999
1186
|
//# sourceMappingURL=index.js.map
|