solid-pianoroll 0.0.16 → 0.0.18

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 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";
46
- 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"};
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,84 +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 [isDown, setIsDown] = solidJs.createSignal(false);
130
- const virtualDimensions = solidJs.createMemo(() => viewPort().calculatePixelDimensions(127 - key().number, 1));
131
- const previousIsBlack = blackKeys.includes((key().number - 1) % 12);
132
- const nextIsBlack = blackKeys.includes((key().number + 1) % 12);
133
- return web.createComponent(solidJs.Show, {
134
- get when() {
135
- return virtualDimensions().size > 0;
136
- },
137
- get children() {
138
- const _el$2 = _tmpl$$8.cloneNode(true);
139
- _el$2.$$mouseup = () => setIsDown(false);
140
- _el$2.$$mousedown = () => setIsDown(true);
141
- web.insert(_el$2, web.createComponent(solidJs.Show, {
142
- get when() {
143
- return key().isBlack && false;
144
- },
145
- get children() {
146
- const _el$3 = _tmpl$$8.cloneNode(true);
147
- web.effect(_p$ => {
148
- const _v$ = styles$3["black-separator"],
149
- _v$2 = `${virtualDimensions().offset}px`,
150
- _v$3 = `${virtualDimensions().size / 2 - 0.25}px`;
151
- _v$ !== _p$._v$ && web.className(_el$3, _p$._v$ = _v$);
152
- _v$2 !== _p$._v$2 && _el$3.style.setProperty("top", _p$._v$2 = _v$2);
153
- _v$3 !== _p$._v$3 && _el$3.style.setProperty("height", _p$._v$3 = _v$3);
154
- return _p$;
155
- }, {
156
- _v$: undefined,
157
- _v$2: undefined,
158
- _v$3: undefined
159
- });
160
- return _el$3;
161
- }
162
- }));
163
- web.effect(_p$ => {
164
- const _v$4 = {
165
- [styles$3["Key"]]: true,
166
- [styles$3["black"]]: key().isBlack,
167
- [styles$3["white"]]: !key().isBlack,
168
- [styles$3["down"]]: isDown()
169
- },
170
- _v$5 = key().name,
171
- _v$6 = key().number % 12,
172
- _v$7 = `${virtualDimensions().offset - (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0)}px`,
173
- _v$8 = `${virtualDimensions().size + (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0) + (!key().isBlack && previousIsBlack ? virtualDimensions().size / 2 : 0)}px`,
174
- _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(", ");
175
- _p$._v$4 = web.classList(_el$2, _v$4, _p$._v$4);
176
- _v$5 !== _p$._v$5 && web.setAttribute(_el$2, "title", _p$._v$5 = _v$5);
177
- _v$6 !== _p$._v$6 && web.setAttribute(_el$2, "data-index", _p$._v$6 = _v$6);
178
- _v$7 !== _p$._v$7 && _el$2.style.setProperty("top", _p$._v$7 = _v$7);
179
- _v$8 !== _p$._v$8 && _el$2.style.setProperty("height", _p$._v$8 = _v$8);
180
- _v$9 !== _p$._v$9 && _el$2.style.setProperty("box-shadow", _p$._v$9 = _v$9);
181
- return _p$;
182
- }, {
183
- _v$4: undefined,
184
- _v$5: undefined,
185
- _v$6: undefined,
186
- _v$7: undefined,
187
- _v$8: undefined,
188
- _v$9: undefined
189
- });
190
- return _el$2;
191
- }
192
- });
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
+ };
193
217
  }
194
- }));
195
- 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
+ });
196
243
  return _el$;
197
244
  })();
198
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
+ };
199
363
  const blackKeys = [1, 3, 6, 8, 10];
200
364
  const keyNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
201
365
  const keys = Array.from({
@@ -211,10 +375,10 @@ var css_248z$2 = ".PianoRollNotes-module_PianoRollNotes__6pF-y {\n position: ab
211
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"};
212
376
  styleInject(css_248z$2);
213
377
 
214
- const _tmpl$$7 = /*#__PURE__*/web.template(`<div></div>`, 2);
378
+ const _tmpl$$6 = /*#__PURE__*/web.template(`<div></div>`, 2);
215
379
  const PianoRollNotes = props => {
216
380
  const context = usePianoRollContext();
217
- const verticalViewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
381
+ const verticalViewPort = solidJs.createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
218
382
  const horizontalViewPort = solidJs.createMemo(() => useViewPortDimension("horizontal"));
219
383
  const gridDivisionTicks = solidJs.createMemo(() => context.ppq * 4 / context.gridDivision);
220
384
  const snapValueToGridIfEnabled = (value, altKey) => context.snapToGrid && !altKey ? Math.round(value / gridDivisionTicks()) * gridDivisionTicks() : value;
@@ -222,7 +386,7 @@ const PianoRollNotes = props => {
222
386
  const position = horizontalViewPort().calculatePosition(event.clientX);
223
387
  const existingNote = currentNote();
224
388
  const midi = context.mode === "keys" ? 127 - Math.floor(verticalViewPort().calculatePosition(event.clientY)) : existingNote?.midi ?? 60;
225
- 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;
226
390
  const eventPositionTicks = Math.floor(position / gridDivisionTicks()) * gridDivisionTicks();
227
391
  const velocity = 127;
228
392
  const ticks = existingNote?.ticks ?? eventPositionTicks;
@@ -250,7 +414,7 @@ const PianoRollNotes = props => {
250
414
  return noteDragMode ? [styles$2.Note, styles$2[noteDragMode]] : [styles$2.Note];
251
415
  };
252
416
  return (() => {
253
- const _el$ = _tmpl$$7.cloneNode(true);
417
+ const _el$ = _tmpl$$6.cloneNode(true);
254
418
  _el$.$$click = event => {
255
419
  if (currentNote()) {
256
420
  setCurrentNoteIndex(-1);
@@ -308,7 +472,7 @@ const PianoRollNotes = props => {
308
472
  return web.memo(() => !!verticalViewPort().isVisible(verticalVirtualDimensions()))() && horizontalViewPort().isVisible(horizontalDimensions());
309
473
  },
310
474
  get children() {
311
- const _el$2 = _tmpl$$7.cloneNode(true);
475
+ const _el$2 = _tmpl$$6.cloneNode(true);
312
476
  _el$2.$$mousedown = event => {
313
477
  event.stopPropagation();
314
478
  setIsDragging(true);
@@ -337,7 +501,7 @@ const PianoRollNotes = props => {
337
501
  };
338
502
  const previousTrackIndex = currentNoteTrackIndex();
339
503
  const previousNoteIndex = currentNoteIndex();
340
- 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;
341
505
  if (targetTrackIndex === previousTrackIndex) {
342
506
  context.onNoteChange?.(previousTrackIndex, previousNoteIndex, updatedNote);
343
507
  } else {
@@ -411,109 +575,6 @@ const PianoRollNotes = props => {
411
575
  };
412
576
  web.delegateEvents(["mousedown", "mousemove", "mouseup", "dblclick", "click"]);
413
577
 
414
- const _tmpl$$6 = /*#__PURE__*/web.template(`<div class="PianoRoll-Scroller"><div><div><div></div></div></div></div>`, 8);
415
- const ScrollContainer = props => {
416
- let scrollContentRef;
417
- const verticalViewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
418
- const horizontalViewPort = solidJs.createMemo(() => useViewPortDimension("horizontal"));
419
- const handleScroll = event => {
420
- event.preventDefault();
421
- if (didUpdateScroll) {
422
- didUpdateScroll = false;
423
- return;
424
- }
425
- const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
426
- const maxPosition = horizontalViewPort().calculateMaxPosition();
427
- const height = verticalViewPort().pixelSize;
428
- const width = horizontalViewPort().pixelSize;
429
- const {
430
- scrollTop,
431
- scrollLeft,
432
- scrollWidth,
433
- scrollHeight
434
- } = event.currentTarget;
435
- const scrollTopAmount = scrollTop / (scrollHeight - height);
436
- const scrollLeftAmount = scrollLeft / (scrollWidth - width);
437
- verticalViewPort().onPositionChange?.(maxVerticalPosition * scrollTopAmount);
438
- horizontalViewPort().onPositionChange?.(maxPosition * scrollLeftAmount);
439
- };
440
- const handleWheel = event => {
441
- if (event.altKey) {
442
- event.preventDefault();
443
- if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) {
444
- horizontalViewPort()?.onZoomChange?.(horizontalViewPort().zoom * (1 + event.deltaX / horizontalViewPort().pixelSize));
445
- const maxPosition = horizontalViewPort().calculateMaxPosition();
446
- horizontalViewPort()?.onPositionChange?.(Math.min(maxPosition, horizontalViewPort()?.position));
447
- } else {
448
- verticalViewPort()?.onZoomChange?.(verticalViewPort().zoom * (1 + event.deltaY / verticalViewPort().pixelSize));
449
- const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
450
- verticalViewPort()?.onPositionChange?.(Math.min(maxVerticalPosition, verticalViewPort()?.position));
451
- }
452
- }
453
- };
454
- let didUpdateScroll = false;
455
- solidJs.createEffect(() => {
456
- const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
457
- const maxPosition = horizontalViewPort().calculateMaxPosition();
458
- const scrollTopAmount = maxVerticalPosition > 0 ? verticalViewPort().position / maxVerticalPosition : 0;
459
- const scrollLeftAmount = maxPosition > 0 ? horizontalViewPort().position / maxPosition : 0;
460
- const height = verticalViewPort().pixelSize;
461
- const width = horizontalViewPort().pixelSize;
462
- if (!scrollContentRef?.parentElement) return;
463
- const scrollDivHeight = verticalViewPort().zoom * verticalViewPort().pixelSize;
464
- const scrollTop = scrollTopAmount * (scrollDivHeight - height);
465
- const scrollDivWidth = horizontalViewPort().zoom * horizontalViewPort().pixelSize;
466
- const scrollLeft = scrollLeftAmount * (scrollDivWidth - width);
467
- didUpdateScroll = true;
468
- scrollContentRef.style.height = `${scrollDivHeight}px`;
469
- scrollContentRef.style.width = `${scrollDivWidth}px`;
470
- scrollContentRef.parentElement.scrollTo({
471
- left: scrollLeft,
472
- top: scrollTop
473
- });
474
- });
475
- return (() => {
476
- const _el$ = _tmpl$$6.cloneNode(true),
477
- _el$2 = _el$.firstChild,
478
- _el$3 = _el$2.firstChild,
479
- _el$4 = _el$3.firstChild;
480
- _el$.addEventListener("wheel", handleWheel);
481
- _el$.addEventListener("scroll", handleScroll);
482
- const _ref$ = props.ref;
483
- typeof _ref$ === "function" ? web.use(_ref$, _el$) : props.ref = _el$;
484
- _el$.style.setProperty("height", "100%");
485
- _el$.style.setProperty("width", "100%");
486
- _el$.style.setProperty("z-index", "4");
487
- _el$.style.setProperty("overflow", "scroll");
488
- _el$.style.setProperty("pointer-events", "auto");
489
- const _ref$2 = scrollContentRef;
490
- typeof _ref$2 === "function" ? web.use(_ref$2, _el$2) : scrollContentRef = _el$2;
491
- _el$3.style.setProperty("top", "0");
492
- _el$3.style.setProperty("left", "0");
493
- _el$3.style.setProperty("position", "sticky");
494
- _el$3.style.setProperty("display", "flex");
495
- _el$4.style.setProperty("position", "relative");
496
- web.insert(_el$4, () => props.children);
497
- web.effect(_p$ => {
498
- const _v$ = `${verticalViewPort().pixelSize}px`,
499
- _v$2 = `${horizontalViewPort().pixelSize}px`,
500
- _v$3 = `${verticalViewPort().pixelSize}px`,
501
- _v$4 = `${horizontalViewPort().pixelSize}px`;
502
- _v$ !== _p$._v$ && _el$3.style.setProperty("height", _p$._v$ = _v$);
503
- _v$2 !== _p$._v$2 && _el$3.style.setProperty("width", _p$._v$2 = _v$2);
504
- _v$3 !== _p$._v$3 && _el$4.style.setProperty("height", _p$._v$3 = _v$3);
505
- _v$4 !== _p$._v$4 && _el$4.style.setProperty("width", _p$._v$4 = _v$4);
506
- return _p$;
507
- }, {
508
- _v$: undefined,
509
- _v$2: undefined,
510
- _v$3: undefined,
511
- _v$4: undefined
512
- });
513
- return _el$;
514
- })();
515
- };
516
-
517
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";
518
579
  var styles$1 = {"PianoRollGrid":"PianoRollGrid-module_PianoRollGrid__tG119","PianoRollGrid-Row":"PianoRollGrid-module_PianoRollGrid-Row__nRMCs","PianoRollGrid-Time":"PianoRollGrid-module_PianoRollGrid-Time__jLz3E"};
519
580
  styleInject(css_248z$1);
@@ -521,7 +582,7 @@ styleInject(css_248z$1);
521
582
  const _tmpl$$5 = /*#__PURE__*/web.template(`<div></div>`, 2);
522
583
  const PianoRollGrid = () => {
523
584
  const context = usePianoRollContext();
524
- const verticalViewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
585
+ const verticalViewPort = solidJs.createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
525
586
  const horizontalViewPort = solidJs.createMemo(() => useViewPortDimension("horizontal"));
526
587
  const measureTicks = solidJs.createMemo(() => context.ppq * 4);
527
588
  const selectedGridDivisorTicks = solidJs.createMemo(() => measureTicks() / context.gridDivision);
@@ -704,14 +765,14 @@ function useBoundingClientRect(containerRef) {
704
765
 
705
766
  const _tmpl$$4 = /*#__PURE__*/web.template(`<input min="1" max="11" step="0.01">`, 1);
706
767
  const VerticalZoomControl = props => {
707
- const context = usePianoRollContext();
768
+ const dimension = solidJs.createMemo(() => useViewPortDimension(props.dimensionName ?? "vertical"));
708
769
  return (() => {
709
770
  const _el$ = _tmpl$$4.cloneNode(true);
710
771
  web.spread(_el$, web.mergeProps(props, {
711
772
  get value() {
712
- return context.verticalZoom;
773
+ return dimension().zoom;
713
774
  },
714
- "onInput": event => context.onVerticalZoomChange?.(event.currentTarget.valueAsNumber),
775
+ "onInput": event => dimension().onZoomChange?.(event.currentTarget.valueAsNumber),
715
776
  "type": "range"
716
777
  }, {
717
778
  orient: "vertical"
@@ -719,6 +780,7 @@ const VerticalZoomControl = props => {
719
780
  get style() {
720
781
  return {
721
782
  width: "16px",
783
+ transform: "rotate(180deg)",
722
784
  ...{
723
785
  "writing-mode": "bt-lr" /* IE */,
724
786
  "-webkit-appearance": "slider-vertical" /* WebKit */
@@ -732,14 +794,14 @@ const VerticalZoomControl = props => {
732
794
 
733
795
  const _tmpl$$3 = /*#__PURE__*/web.template(`<input max="500" min="1" step="0.01">`, 1);
734
796
  const HorizontalZoomControl = props => {
735
- const context = usePianoRollContext();
797
+ const dimension = solidJs.createMemo(() => useViewPortDimension(props.dimensionName ?? "horizontal"));
736
798
  return (() => {
737
799
  const _el$ = _tmpl$$3.cloneNode(true);
738
800
  web.spread(_el$, web.mergeProps(props, {
739
801
  get value() {
740
- return context.zoom;
802
+ return dimension().zoom;
741
803
  },
742
- "onInput": event => context.onZoomChange?.(event.currentTarget.valueAsNumber),
804
+ "onInput": event => dimension().onZoomChange?.(event.currentTarget.valueAsNumber),
743
805
  "type": "range",
744
806
  get style() {
745
807
  return {
@@ -760,7 +822,7 @@ styleInject(css_248z);
760
822
  const _tmpl$$2 = /*#__PURE__*/web.template(`<div></div>`, 2),
761
823
  _tmpl$2$1 = /*#__PURE__*/web.template(`<div> </div>`, 2);
762
824
  const PianoRollTrackList = () => {
763
- const viewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
825
+ const viewPort = solidJs.createMemo(() => useViewPortDimension("verticalTracks"));
764
826
  const context = usePianoRollContext();
765
827
  return (() => {
766
828
  const _el$ = _tmpl$$2.cloneNode(true);
@@ -769,7 +831,7 @@ const PianoRollTrackList = () => {
769
831
  return context.tracks;
770
832
  },
771
833
  children: (track, index) => {
772
- 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));
773
835
  return web.createComponent(solidJs.Show, {
774
836
  get when() {
775
837
  return virtualDimensions().size > 0;
@@ -813,100 +875,149 @@ const PianoRollTrackList = () => {
813
875
  };
814
876
  web.delegateEvents(["click"]);
815
877
 
816
- const _tmpl$$1 = /*#__PURE__*/web.template(`<div></div>`, 2),
817
- _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);
818
880
  const PianoRoll = allProps => {
819
- const [contextProps, divProps] = splitContextProps(allProps);
881
+ const propsWithDefaults = solidJs.mergeProps({
882
+ showAllTracks: false
883
+ }, allProps);
884
+ const [context, divProps] = splitContextProps(propsWithDefaults);
820
885
  const [scrollerRef, setScrollerRef] = solidJs.createSignal();
886
+ const [trackScrollerRef, setTrackScrollerRef] = solidJs.createSignal();
821
887
  const clientRect = useBoundingClientRect(scrollerRef);
888
+ const trackClientRef = useBoundingClientRect(trackScrollerRef);
822
889
  const zoomFactor = 500;
823
890
  const minZoom = solidJs.createMemo(() => 1 / (zoomFactor / clientRect().width));
824
891
  const maxZoom = solidJs.createMemo(() => 500 * (zoomFactor / clientRect().width));
825
892
  const minVerticalZoom = solidJs.createMemo(() => 1 / (zoomFactor / clientRect().height));
826
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));
827
896
  solidJs.createEffect(isInitial => {
828
897
  if (isInitial) return false;
829
- if (contextProps.mode === "tracks") {
830
- contextProps.onVerticalPositionChange?.(0);
898
+ if (context.mode === "tracks") {
899
+ context.onVerticalPositionChange?.(0);
831
900
  }
832
901
  }, true);
833
902
  return web.createComponent(PianoRollContextProvider, {
834
- value: contextProps,
903
+ value: context,
835
904
  get children() {
836
- const _el$ = _tmpl$2.cloneNode(true),
837
- _el$2 = _el$.firstChild;
905
+ const _el$ = _tmpl$2.cloneNode(true);
838
906
  web.spread(_el$, web.mergeProps(divProps, {
839
907
  get ["class"]() {
840
- return styles$4.PianoRoll;
908
+ return styles$5.PianoRoll;
841
909
  }
842
910
  }), false, true);
843
- web.insert(_el$2, web.createComponent(ScrollZoomViewPort, {
911
+ web.insert(_el$, web.createComponent(ScrollZoomViewPort, {
844
912
  dimensions: {
845
913
  horizontal: () => ({
846
914
  pixelOffset: clientRect().left,
847
915
  pixelSize: clientRect().width,
848
- position: contextProps.position,
849
- range: contextProps.duration,
850
- zoom: contextProps.zoom * (zoomFactor / clientRect().width),
851
- onPositionChange: contextProps.onPositionChange,
852
- 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()))
853
921
  }),
854
922
  vertical: () => ({
855
923
  pixelOffset: clientRect().top,
856
924
  pixelSize: clientRect().height,
857
- position: contextProps.verticalPosition,
858
- range: contextProps.mode === "keys" ? 128 : Math.max(contextProps.tracks.length, 16),
859
- zoom: contextProps.verticalZoom * (zoomFactor / clientRect().height),
860
- onPositionChange: contextProps.onVerticalPositionChange,
861
- 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()))
862
946
  })
863
947
  },
864
948
  get children() {
865
949
  return [(() => {
866
- 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);
867
961
  _el$3.style.setProperty("display", "flex");
868
962
  _el$3.style.setProperty("width", "20%");
869
963
  web.insert(_el$3, web.createComponent(solidJs.Show, {
870
964
  get when() {
871
- return allProps.showTrackList;
965
+ return context.showTrackList;
872
966
  },
873
967
  get children() {
874
- 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
+ });
875
979
  }
876
980
  }), null);
877
981
  web.insert(_el$3, web.createComponent(solidJs.Show, {
878
982
  get when() {
879
- return contextProps.mode === "keys";
983
+ return context.mode === "keys";
880
984
  },
881
985
  get children() {
882
986
  return web.createComponent(PianoRollKeys, {});
883
987
  }
884
988
  }), null);
885
- return _el$3;
886
- })(), web.createComponent(ScrollContainer, {
887
- ref: setScrollerRef,
888
- get children() {
889
- return [web.memo(() => allProps.children), web.createComponent(PianoRollGrid, {}), web.createComponent(PianoRollNotes, {})];
890
- }
891
- }), 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, {
892
1012
  get min() {
893
- return minVerticalZoom();
1013
+ return minZoom();
894
1014
  },
895
1015
  get max() {
896
- return maxVerticalZoom();
1016
+ return maxZoom();
897
1017
  }
898
1018
  })];
899
1019
  }
900
1020
  }));
901
- web.insert(_el$, web.createComponent(HorizontalZoomControl, {
902
- get min() {
903
- return minZoom();
904
- },
905
- get max() {
906
- return maxZoom();
907
- }
908
- }), null);
909
- web.effect(() => web.className(_el$2, styles$4.PianoRollContainer));
910
1021
  return _el$;
911
1022
  }
912
1023
  });
@@ -990,40 +1101,86 @@ const useNotes = () => {
990
1101
  };
991
1102
  };
992
1103
 
993
- const usePianoRoll = () => {
994
- const [ppq, onPpqChange] = solidJs.createSignal(120);
995
- const [mode, onModeChange] = solidJs.createSignal("tracks");
996
- const [position, onPositionChange] = solidJs.createSignal(0);
997
- const [zoom, onZoomChange] = solidJs.createSignal(10);
998
- const [verticalZoom, onVerticalZoomChange] = solidJs.createSignal(5);
999
- const [verticalPosition, onVerticalPositionChange] = solidJs.createSignal(44);
1000
- const [gridDivision, onGridDivisionChange] = solidJs.createSignal(4);
1001
- const [snapToGrid, onSnapToGridChange] = solidJs.createSignal(true);
1002
- const [duration, onDurationChange] = solidJs.createSignal(0);
1003
- return {
1004
- 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, {
1005
1162
  onPpqChange,
1006
- position,
1163
+ onModeChange,
1007
1164
  onPositionChange,
1008
- zoom,
1009
1165
  onZoomChange,
1010
- verticalPosition,
1011
- onVerticalPositionChange,
1012
- verticalZoom,
1013
1166
  onVerticalZoomChange,
1014
- gridDivision,
1167
+ onVerticalPositionChange,
1168
+ onVerticalTrackZoomChange,
1169
+ onVerticalTrackPositionChange,
1015
1170
  onGridDivisionChange,
1016
- snapToGrid,
1017
1171
  onSnapToGridChange,
1018
- mode,
1019
- onModeChange,
1020
- duration,
1021
- onDurationChange
1022
- };
1172
+ onDurationChange,
1173
+ onTracksChange,
1174
+ onNoteChange,
1175
+ onInsertNote,
1176
+ onRemoveNote,
1177
+ onSelectedTrackIndexChange,
1178
+ onPressedKeysChange
1179
+ });
1023
1180
  };
1024
1181
 
1025
1182
  exports.PianoRoll = PianoRoll;
1026
1183
  exports.PlayHead = PlayHead;
1184
+ exports.createPianoRollstate = createPianoRollstate;
1027
1185
  exports.useNotes = useNotes;
1028
- exports.usePianoRoll = usePianoRoll;
1029
1186
  //# sourceMappingURL=index.js.map