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 CHANGED
@@ -29,9 +29,9 @@ function styleInject(css, ref) {
29
29
  }
30
30
  }
31
31
 
32
- var css_248z$4 = ".PianoRoll-module_PianoRoll__rkRYx {\n box-sizing: border-box;\n display: flex;\n overflow: hidden;\n flex-direction: column;\n}\n\n.PianoRoll-module_PianoRollContainer__Oyxr7 {\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: row;\n}\n";
33
- var styles$4 = {"PianoRoll":"PianoRoll-module_PianoRoll__rkRYx","PianoRollContainer":"PianoRoll-module_PianoRollContainer__Oyxr7"};
34
- styleInject(css_248z$4);
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", "duration", "gridDivision", "tracks", "position", "ppq", "snapToGrid", "verticalPosition", "verticalZoom", "zoom", "onInsertNote", "onNoteChange", "onPositionChange", "onRemoveNote", "onVerticalPositionChange", "onVerticalZoomChange", "onZoomChange", "showAllTracks", "selectedTrackIndex", "onSelectedTrackIndexChange"]);
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$3 = ".PianoRollKeys-module_PianoRollKeys__5vnQ0 {\n position: relative;\n height: 100%;\n width: 50px;\n}\n\n.PianoRollKeys-module_Key__jybNC {\n border-width: 0px;\n position: absolute;\n box-sizing: border-box;\n width: 100%;\n border-color: #000;\n border-style: solid;\n border-right-width: 1px;\n}\n\n.PianoRollKeys-module_black__7rncB {\n background: black;\n}\n\n.PianoRollKeys-module_white__fR2Lm {\n background: white;\n}\n\n.PianoRollKeys-module_whiteAndNextIsWhite__PN1O8 {\n border-top-width: 0.1px;\n}\n\n.PianoRollKeys-module_whiteAndPreviousIsWhite__-fP3q {\n border-bottom-width: 0.1px;\n}\n";
46
- var styles$3 = {"PianoRollKeys":"PianoRollKeys-module_PianoRollKeys__5vnQ0","Key":"PianoRollKeys-module_Key__jybNC","black":"PianoRollKeys-module_black__7rncB","white":"PianoRollKeys-module_white__fR2Lm","whiteAndNextIsWhite":"PianoRollKeys-module_whiteAndNextIsWhite__PN1O8","whiteAndPreviousIsWhite":"PianoRollKeys-module_whiteAndPreviousIsWhite__-fP3q"};
47
- styleInject(css_248z$3);
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
- const _tmpl$$8 = /*#__PURE__*/web.template(`<div></div>`, 2);
122
- const PianoRollKeys = () => {
123
- const viewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
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
- web.insert(_el$, web.createComponent(solidJs.Index, {
127
- each: keys,
128
- children: key => {
129
- const virtualDimensions = solidJs.createMemo(() => viewPort().calculatePixelDimensions(127 - key().number, 1));
130
- return web.createComponent(solidJs.Show, {
131
- get when() {
132
- return virtualDimensions().size > 0;
133
- },
134
- get children() {
135
- const _el$2 = _tmpl$$8.cloneNode(true);
136
- web.effect(_p$ => {
137
- const _v$ = {
138
- [styles$3["Key"]]: true,
139
- [styles$3["black"]]: key().isBlack,
140
- [styles$3["white"]]: !key().isBlack,
141
- [styles$3["whiteAndNextIsWhite"]]: !key().isBlack && !blackKeys.includes((key().number + 1) % 12),
142
- [styles$3["whiteAndPreviousIsWhite"]]: !key().isBlack && !blackKeys.includes((key().number - 1) % 12)
143
- },
144
- _v$2 = key().name,
145
- _v$3 = key().number % 12,
146
- _v$4 = `${virtualDimensions().offset}px`,
147
- _v$5 = `${virtualDimensions().size}px`;
148
- _p$._v$ = web.classList(_el$2, _v$, _p$._v$);
149
- _v$2 !== _p$._v$2 && web.setAttribute(_el$2, "title", _p$._v$2 = _v$2);
150
- _v$3 !== _p$._v$3 && web.setAttribute(_el$2, "data-index", _p$._v$3 = _v$3);
151
- _v$4 !== _p$._v$4 && _el$2.style.setProperty("top", _p$._v$4 = _v$4);
152
- _v$5 !== _p$._v$5 && _el$2.style.setProperty("height", _p$._v$5 = _v$5);
153
- return _p$;
154
- }, {
155
- _v$: undefined,
156
- _v$2: undefined,
157
- _v$3: undefined,
158
- _v$4: undefined,
159
- _v$5: undefined
160
- });
161
- return _el$2;
162
- }
163
- });
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
- web.effect(() => web.className(_el$, styles$3.PianoRollKeys));
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$$7 = /*#__PURE__*/web.template(`<div></div>`, 2);
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$$7.cloneNode(true);
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$$7.cloneNode(true);
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 context = usePianoRollContext();
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 context.verticalZoom;
773
+ return dimension().zoom;
683
774
  },
684
- "onInput": event => context.onVerticalZoomChange?.(event.currentTarget.valueAsNumber),
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 context = usePianoRollContext();
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 context.zoom;
802
+ return dimension().zoom;
711
803
  },
712
- "onInput": event => context.onZoomChange?.(event.currentTarget.valueAsNumber),
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("vertical"));
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(context.mode === "tracks" ? index : index * 8, context.mode === "tracks" ? 1 : 8));
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>`, 2),
787
- _tmpl$2 = /*#__PURE__*/web.template(`<div><div></div></div>`, 4);
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 [contextProps, divProps] = splitContextProps(allProps);
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 (contextProps.mode === "tracks") {
800
- contextProps.onVerticalPositionChange?.(0);
898
+ if (context.mode === "tracks") {
899
+ context.onVerticalPositionChange?.(0);
801
900
  }
802
901
  }, true);
803
902
  return web.createComponent(PianoRollContextProvider, {
804
- value: contextProps,
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$4.PianoRoll;
908
+ return styles$5.PianoRoll;
811
909
  }
812
910
  }), false, true);
813
- web.insert(_el$2, web.createComponent(ScrollZoomViewPort, {
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: contextProps.position,
819
- range: contextProps.duration,
820
- zoom: contextProps.zoom * (zoomFactor / clientRect().width),
821
- onPositionChange: contextProps.onPositionChange,
822
- onZoomChange: zoom => contextProps.onZoomChange?.(clamp(zoom / (zoomFactor / clientRect().width), minZoom(), maxZoom()))
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: contextProps.verticalPosition,
828
- range: contextProps.mode === "keys" ? 128 : Math.max(contextProps.tracks.length, 16),
829
- zoom: contextProps.verticalZoom * (zoomFactor / clientRect().height),
830
- onPositionChange: contextProps.onVerticalPositionChange,
831
- onZoomChange: verticalZoom => contextProps.onVerticalZoomChange?.(clamp(verticalZoom / (zoomFactor / clientRect().height), minVerticalZoom(), maxVerticalZoom()))
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$3 = _tmpl$$1.cloneNode(true);
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 allProps.showTrackList;
965
+ return context.showTrackList;
842
966
  },
843
967
  get children() {
844
- return web.createComponent(PianoRollTrackList, {});
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 contextProps.mode === "keys";
983
+ return context.mode === "keys";
850
984
  },
851
985
  get children() {
852
986
  return web.createComponent(PianoRollKeys, {});
853
987
  }
854
988
  }), null);
855
- return _el$3;
856
- })(), web.createComponent(ScrollContainer, {
857
- ref: setScrollerRef,
858
- get children() {
859
- return [web.memo(() => allProps.children), web.createComponent(PianoRollGrid, {}), web.createComponent(PianoRollNotes, {})];
860
- }
861
- }), web.createComponent(VerticalZoomControl, {
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 minVerticalZoom();
1013
+ return minZoom();
864
1014
  },
865
1015
  get max() {
866
- return maxVerticalZoom();
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 usePianoRoll = () => {
964
- const [ppq, onPpqChange] = solidJs.createSignal(120);
965
- const [mode, onModeChange] = solidJs.createSignal("tracks");
966
- const [position, onPositionChange] = solidJs.createSignal(0);
967
- const [zoom, onZoomChange] = solidJs.createSignal(10);
968
- const [verticalZoom, onVerticalZoomChange] = solidJs.createSignal(5);
969
- const [verticalPosition, onVerticalPositionChange] = solidJs.createSignal(44);
970
- const [gridDivision, onGridDivisionChange] = solidJs.createSignal(4);
971
- const [snapToGrid, onSnapToGridChange] = solidJs.createSignal(true);
972
- const [duration, onDurationChange] = solidJs.createSignal(0);
973
- return {
974
- ppq,
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
- position,
1163
+ onModeChange,
977
1164
  onPositionChange,
978
- zoom,
979
1165
  onZoomChange,
980
- verticalPosition,
981
- onVerticalPositionChange,
982
- verticalZoom,
983
1166
  onVerticalZoomChange,
984
- gridDivision,
1167
+ onVerticalPositionChange,
1168
+ onVerticalTrackZoomChange,
1169
+ onVerticalTrackPositionChange,
985
1170
  onGridDivisionChange,
986
- snapToGrid,
987
1171
  onSnapToGridChange,
988
- mode,
989
- onModeChange,
990
- duration,
991
- onDurationChange
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