solid-pianoroll 0.0.22 → 0.0.23

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$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\n.PianoRoll-module_PianoRollLeftColumn__S6SZQ {\n display: flex;\n width: 30%;\n max-width: 250px;\n}\n";
33
- var styles$5 = {"PianoRoll":"PianoRoll-module_PianoRoll__rkRYx","PianoRollContainer":"PianoRoll-module_PianoRollContainer__Oyxr7","PianoRollLeftColumn":"PianoRoll-module_PianoRollLeftColumn__S6SZQ"};
34
- styleInject(css_248z$5);
32
+ var css_248z$6 = ".PianoRoll-module_PianoRoll__rkRYx {\n box-sizing: border-box;\n display: flex;\n overflow: hidden;\n flex-direction: column;\n height: 100%;\n user-select: none;\n}\n\n.PianoRoll-module_PianoRollContainer__Oyxr7 {\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: row;\n}\n\n.PianoRoll-module_PianoRollLeftColumn__S6SZQ {\n display: flex;\n overflow: hidden;\n flex-direction: column;\n max-width: 250px;\n margin-top: 30px;\n}\n.PianoRoll-module_PianoRollLeftColumn__S6SZQ.PianoRoll-module_showTrackList__mqsrT {\n width: 30%;\n margin-top: 0;\n}\n\n.PianoRoll-module_PianoRollRightColumn__V98HV {\n display: flex;\n position: relative;\n flex-direction: column;\n flex: 1;\n height: 100%;\n}\n";
33
+ var styles$6 = {"PianoRoll":"PianoRoll-module_PianoRoll__rkRYx","PianoRollContainer":"PianoRoll-module_PianoRollContainer__Oyxr7","PianoRollLeftColumn":"PianoRoll-module_PianoRollLeftColumn__S6SZQ","showTrackList":"PianoRoll-module_showTrackList__mqsrT","PianoRollRightColumn":"PianoRoll-module_PianoRollRightColumn__V98HV"};
34
+ styleInject(css_248z$6);
35
35
 
36
36
  const defaultState = {
37
37
  ppq: 0,
@@ -47,7 +47,19 @@ const defaultState = {
47
47
  duration: 0,
48
48
  tracks: [],
49
49
  selectedTrackIndex: 0,
50
- pressedKeys: {}
50
+ pressedKeys: {},
51
+ notesScrollerClientRect: {
52
+ left: 0,
53
+ width: 0,
54
+ top: 0,
55
+ height: 0
56
+ },
57
+ tracksScrollerClientRect: {
58
+ left: 0,
59
+ width: 0,
60
+ top: 0,
61
+ height: 0
62
+ }
51
63
  };
52
64
  const propNameToHandlerName = name => `on${name[0]?.toUpperCase()}${name.slice(1)}Change`;
53
65
  const pianoRollStatePropNames = [...Object.keys(defaultState), ...Object.keys(defaultState).map(propNameToHandlerName), "onNoteChange", "onInsertNote", "onRemoveNote", "onNoteDown", "onNoteUp", "isKeyDown"];
@@ -120,9 +132,9 @@ const usePianoRollContext = () => {
120
132
  };
121
133
  const splitContextProps = allProps => solidJs.splitProps(allProps, [...pianoRollStatePropNames, "showAllTracks", "showTrackList"]);
122
134
 
123
- var css_248z$4 = ".PianoRollKeys-module_PianoRollKeys__5vnQ0 {\n position: relative;\n height: 100%;\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}\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 transform: rotateX(0deg);\n perspective: 100px;\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 border: 1px black outset;\n}\n\n.PianoRollKeys-module_white__fR2Lm {\n background: white;\n border-top-width: 0.5px;\n border-bottom-width: 0.5px;\n border-top-right-radius: 4%;\n border-bottom-right-radius: 4%;\n}\n\n.PianoRollKeys-module_down__GcNeZ {\n transition: none;\n background: red;\n transform: rotateX(0deg) rotateY(20deg);\n}\n";
124
- 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"};
125
- styleInject(css_248z$4);
135
+ var css_248z$5 = ".PianoRollKeys-module_PianoRollKeys__5vnQ0 {\n position: relative;\n height: 100%;\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}\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 transform: rotateX(0deg);\n perspective: 100px;\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 border: 1px black outset;\n}\n\n.PianoRollKeys-module_white__fR2Lm {\n background: white;\n border-top-width: 0.5px;\n border-bottom-width: 0.5px;\n border-top-right-radius: 4%;\n border-bottom-right-radius: 4%;\n}\n\n.PianoRollKeys-module_down__GcNeZ {\n transition: none;\n background: red;\n transform: rotateX(0deg) rotateY(20deg);\n}\n";
136
+ var styles$5 = {"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"};
137
+ styleInject(css_248z$5);
126
138
 
127
139
  function createViewPortDimension(getState) {
128
140
  const getStateWithFunctions = () => {
@@ -212,11 +224,11 @@ const useViewPortDimension = name => {
212
224
  return viewPort;
213
225
  };
214
226
 
215
- var css_248z$3 = ".ScrollZoomContainer-module_ScrollZoomContainer__o2bRt {\n height: 100%;\n width: 100%;\n z-index: 4;\n}\n";
216
- var styles$3 = {"ScrollZoomContainer":"ScrollZoomContainer-module_ScrollZoomContainer__o2bRt"};
217
- styleInject(css_248z$3);
227
+ var css_248z$4 = ".ScrollZoomContainer-module_ScrollZoomContainer__o2bRt {\n height: 100%;\n width: 100%;\n z-index: 4;\n}\n";
228
+ var styles$4 = {"ScrollZoomContainer":"ScrollZoomContainer-module_ScrollZoomContainer__o2bRt"};
229
+ styleInject(css_248z$4);
218
230
 
219
- const _tmpl$$7 = /*#__PURE__*/web.template(`<div><div><div><div></div></div></div></div>`, 8);
231
+ const _tmpl$$8 = /*#__PURE__*/web.template(`<div><div><div><div></div></div></div></div>`, 8);
220
232
  const ScrollZoomContainer = props => {
221
233
  let scrollContentRef;
222
234
  const [ownProps, divProps] = solidJs.splitProps(props, ["ref", "verticalDimensionName", "horizontalDimensionName", "showScrollbar"]);
@@ -252,11 +264,11 @@ const ScrollZoomContainer = props => {
252
264
  if (event.altKey) {
253
265
  event.preventDefault();
254
266
  if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) {
255
- horizontalViewPort()?.onZoomChange?.(horizontalViewPort().zoom * (1 + event.deltaX / horizontalViewPort().pixelSize));
267
+ horizontalViewPort()?.onZoomChange?.(horizontalViewPort().zoom / (1 + event.deltaX / horizontalViewPort().pixelSize));
256
268
  const maxPosition = horizontalViewPort().calculateMaxPosition();
257
269
  horizontalViewPort()?.onPositionChange?.(Math.min(maxPosition, horizontalViewPort()?.position));
258
270
  } else {
259
- verticalViewPort()?.onZoomChange?.(verticalViewPort().zoom * (1 + event.deltaY / verticalViewPort().pixelSize));
271
+ verticalViewPort()?.onZoomChange?.(verticalViewPort().zoom / (1 + event.deltaY / verticalViewPort().pixelSize));
260
272
  const maxVerticalPosition = verticalViewPort().calculateMaxPosition();
261
273
  verticalViewPort()?.onPositionChange?.(Math.min(maxVerticalPosition, verticalViewPort()?.position));
262
274
  }
@@ -288,7 +300,7 @@ const ScrollZoomContainer = props => {
288
300
  });
289
301
  });
290
302
  return (() => {
291
- const _el$ = _tmpl$$7.cloneNode(true),
303
+ const _el$ = _tmpl$$8.cloneNode(true),
292
304
  _el$2 = _el$.firstChild,
293
305
  _el$3 = _el$2.firstChild,
294
306
  _el$4 = _el$3.firstChild;
@@ -305,7 +317,7 @@ const ScrollZoomContainer = props => {
305
317
  },
306
318
  get classList() {
307
319
  return {
308
- [styles$3.ScrollZoomContainer]: true,
320
+ [styles$4.ScrollZoomContainer]: true,
309
321
  ...divProps.classList
310
322
  };
311
323
  }
@@ -338,7 +350,7 @@ const ScrollZoomContainer = props => {
338
350
  })();
339
351
  };
340
352
 
341
- const _tmpl$$6 = /*#__PURE__*/web.template(`<div></div>`, 2);
353
+ const _tmpl$$7 = /*#__PURE__*/web.template(`<div></div>`, 2);
342
354
  const PianoRollKeys = () => {
343
355
  const verticalViewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
344
356
  const horizontalViewPort = solidJs.createMemo(() => useViewPortDimension("horizontalKeys"));
@@ -355,7 +367,7 @@ const PianoRollKeys = () => {
355
367
  }
356
368
  });
357
369
  return (() => {
358
- const _el$ = _tmpl$$6.cloneNode(true);
370
+ const _el$ = _tmpl$$7.cloneNode(true);
359
371
  web.insert(_el$, web.createComponent(ScrollZoomContainer, {
360
372
  horizontalDimensionName: "horizontalKeys",
361
373
  showScrollbar: false,
@@ -369,10 +381,10 @@ const PianoRollKeys = () => {
369
381
  const nextIsBlack = blackKeys.includes((key().number + 1) % 12);
370
382
  return web.createComponent(solidJs.Show, {
371
383
  get when() {
372
- return virtualDimensions().size > 0;
384
+ return verticalViewPort().isVisible(virtualDimensions());
373
385
  },
374
386
  get children() {
375
- const _el$2 = _tmpl$$6.cloneNode(true);
387
+ const _el$2 = _tmpl$$7.cloneNode(true);
376
388
  _el$2.addEventListener("mouseleave", () => {
377
389
  if (isMouseDown()) {
378
390
  context.onNoteUp(context.selectedTrackIndex, key().number);
@@ -392,16 +404,16 @@ const PianoRollKeys = () => {
392
404
  };
393
405
  web.effect(_p$ => {
394
406
  const _v$3 = {
395
- [styles$4["Key"]]: true,
396
- [styles$4["black"]]: key().isBlack,
397
- [styles$4["white"]]: !key().isBlack,
398
- [styles$4["down"]]: isDown()
407
+ [styles$5["Key"]]: true,
408
+ [styles$5["black"]]: key().isBlack,
409
+ [styles$5["white"]]: !key().isBlack,
410
+ [styles$5["down"]]: isDown()
399
411
  },
400
412
  _v$4 = key().name,
401
413
  _v$5 = key().number % 12,
402
414
  _v$6 = `${virtualDimensions().offset - virtualDimensions().size * (!key().isBlack ? nextIsBlack ? 1 / 2 : 0 : 0)}px`,
403
415
  _v$7 = `${virtualDimensions().size + (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0) + (!key().isBlack && previousIsBlack ? virtualDimensions().size / 2 : 0)}px`,
404
- _v$8 = [`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(", ");
416
+ _v$8 = `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` : "";
405
417
  _p$._v$3 = web.classList(_el$2, _v$3, _p$._v$3);
406
418
  _v$4 !== _p$._v$4 && web.setAttribute(_el$2, "title", _p$._v$4 = _v$4);
407
419
  _v$5 !== _p$._v$5 && web.setAttribute(_el$2, "data-index", _p$._v$5 = _v$5);
@@ -425,7 +437,7 @@ const PianoRollKeys = () => {
425
437
  }
426
438
  }));
427
439
  web.effect(_p$ => {
428
- const _v$ = styles$4.PianoRollKeys,
440
+ const _v$ = styles$5.PianoRollKeys,
429
441
  _v$2 = `${horizontalViewPort().pixelSize}px`;
430
442
  _v$ !== _p$._v$ && web.className(_el$, _p$._v$ = _v$);
431
443
  _v$2 !== _p$._v$2 && _el$.style.setProperty("width", _p$._v$2 = _v$2);
@@ -448,11 +460,11 @@ const keys = Array.from({
448
460
  }));
449
461
  web.delegateEvents(["mousedown", "mouseup"]);
450
462
 
451
- 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}";
452
- var styles$2 = {"PianoRollNotes":"PianoRollNotes-module_PianoRollNotes__6pF-y","Note":"PianoRollNotes-module_Note__-jxLb","trimStart":"PianoRollNotes-module_trimStart__vuBlj","trimEnd":"PianoRollNotes-module_trimEnd__zPdjr"};
453
- styleInject(css_248z$2);
463
+ var css_248z$3 = ".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}";
464
+ var styles$3 = {"PianoRollNotes":"PianoRollNotes-module_PianoRollNotes__6pF-y","Note":"PianoRollNotes-module_Note__-jxLb","trimStart":"PianoRollNotes-module_trimStart__vuBlj","trimEnd":"PianoRollNotes-module_trimEnd__zPdjr"};
465
+ styleInject(css_248z$3);
454
466
 
455
- const _tmpl$$5 = /*#__PURE__*/web.template(`<div></div>`, 2);
467
+ const _tmpl$$6 = /*#__PURE__*/web.template(`<div></div>`, 2);
456
468
  const PianoRollNotes = props => {
457
469
  const context = usePianoRollContext();
458
470
  const verticalViewPort = solidJs.createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
@@ -476,6 +488,8 @@ const PianoRollNotes = props => {
476
488
  };
477
489
  };
478
490
  const handleMouseMove = mouseMoveEvent => {
491
+ mouseMoveEvent.preventDefault();
492
+ mouseMoveEvent.stopPropagation();
479
493
  const note = getInitialNote();
480
494
  if (!note) return;
481
495
  const {
@@ -516,17 +530,21 @@ const PianoRollNotes = props => {
516
530
  window.removeEventListener("mousemove", handleMouseMove);
517
531
  window.removeEventListener("mouseup", stopDragging);
518
532
  setIsDragging(false);
533
+ setCurrentNoteIndex(-1);
534
+ setCurrentNoteTrackIndex(-1);
519
535
  };
520
536
  const startDragging = () => {
521
537
  window.addEventListener("mousemove", handleMouseMove);
522
538
  window.addEventListener("mouseup", stopDragging);
523
539
  };
524
540
  const getClasses = noteDragMode => {
525
- return noteDragMode ? [styles$2.Note, styles$2[noteDragMode]] : [styles$2.Note];
541
+ return noteDragMode ? [styles$3.Note, styles$3[noteDragMode]] : [styles$3.Note];
526
542
  };
527
543
  return (() => {
528
- const _el$ = _tmpl$$5.cloneNode(true);
544
+ const _el$ = _tmpl$$6.cloneNode(true);
529
545
  _el$.$$mousedown = mouseDownEvent => {
546
+ mouseDownEvent.preventDefault();
547
+ mouseDownEvent.stopPropagation();
530
548
  const {
531
549
  targetTrackIndex,
532
550
  midi,
@@ -573,7 +591,7 @@ const PianoRollNotes = props => {
573
591
  return web.memo(() => !!verticalViewPort().isVisible(verticalVirtualDimensions()))() && horizontalViewPort().isVisible(horizontalDimensions());
574
592
  },
575
593
  get children() {
576
- const _el$2 = _tmpl$$5.cloneNode(true);
594
+ const _el$2 = _tmpl$$6.cloneNode(true);
577
595
  _el$2.$$mousedown = event => {
578
596
  event.stopPropagation();
579
597
  const initialPosition = horizontalViewPort().calculatePosition(event.clientX);
@@ -629,21 +647,19 @@ const PianoRollNotes = props => {
629
647
  }
630
648
  }));
631
649
  web.effect(_$p => web.classList(_el$, {
632
- [styles$2.PianoRollNotes]: true
650
+ [styles$3.PianoRollNotes]: true
633
651
  }, _$p));
634
652
  return _el$;
635
653
  })();
636
654
  };
637
655
  web.delegateEvents(["mousedown", "mousemove", "dblclick"]);
638
656
 
639
- 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";
640
- var styles$1 = {"PianoRollGrid":"PianoRollGrid-module_PianoRollGrid__tG119","PianoRollGrid-Row":"PianoRollGrid-module_PianoRollGrid-Row__nRMCs","PianoRollGrid-Time":"PianoRollGrid-module_PianoRollGrid-Time__jLz3E"};
641
- styleInject(css_248z$1);
657
+ var css_248z$2 = ".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 width: 100%;\n border-width: 0;\n}\n.PianoRollGrid-module_PianoRollGrid-Row__nRMCs.PianoRollGrid-module_IsDark__jRyyy {\n background-color: rgba(0, 0, 0, 0.2);\n}\n\n.PianoRollGrid-module_PianoRollGrid-Row__nRMCs.PianoRollGrid-module_Key__8ZwPN {\n border-width: 0px 1px 0px 0;\n}\n.PianoRollGrid-module_PianoRollGrid-Row__nRMCs.PianoRollGrid-module_IsBlackAndNextIsWhite__UF8O2 {\n background-color: rgba(0, 0, 0, 0.2);\n border-width: 0.1px 1px 0.1px 0;\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 border-left-color: #bbb;\n background: #ccc;\n}\n\n.PianoRollGrid-module_PianoRollGrid-Time__jLz3E.PianoRollGrid-module_Highlighted__N1J6q {\n background: #ddd;\n}\n\n.PianoRollGrid-module_PianoRollGrid-Time__jLz3E.PianoRollGrid-module_HighlightedBorder__Vnrff {\n border-left-color: gray;\n}\n";
658
+ var styles$2 = {"PianoRollGrid":"PianoRollGrid-module_PianoRollGrid__tG119","PianoRollGrid-Row":"PianoRollGrid-module_PianoRollGrid-Row__nRMCs","IsDark":"PianoRollGrid-module_IsDark__jRyyy","Key":"PianoRollGrid-module_Key__8ZwPN","IsBlackAndNextIsWhite":"PianoRollGrid-module_IsBlackAndNextIsWhite__UF8O2","PianoRollGrid-Time":"PianoRollGrid-module_PianoRollGrid-Time__jLz3E","Highlighted":"PianoRollGrid-module_Highlighted__N1J6q","HighlightedBorder":"PianoRollGrid-module_HighlightedBorder__Vnrff"};
659
+ styleInject(css_248z$2);
642
660
 
643
- const _tmpl$$4 = /*#__PURE__*/web.template(`<div></div>`, 2);
644
- const PianoRollGrid = () => {
661
+ const usePianoRollGrid = () => {
645
662
  const context = usePianoRollContext();
646
- const verticalViewPort = solidJs.createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
647
663
  const horizontalViewPort = solidJs.createMemo(() => useViewPortDimension("horizontal"));
648
664
  const measureTicks = solidJs.createMemo(() => context.ppq * 4);
649
665
  const selectedGridDivisorTicks = solidJs.createMemo(() => measureTicks() / context.gridDivision);
@@ -664,43 +680,62 @@ const PianoRollGrid = () => {
664
680
  const startIndex = Math.floor(context.position / gridDivisorTicks());
665
681
  return Array.from({
666
682
  length: numberOfLines
667
- }).map((_, index) => ({
668
- index: index + startIndex,
669
- ticks: (index + startIndex) * gridDivisorTicks()
670
- }));
683
+ }).map((_, i) => {
684
+ const index = i + startIndex;
685
+ const ticks = index * gridDivisorTicks();
686
+ const measurePosition = ticks / context.ppq / 4 + 1;
687
+ const bars = Math.floor(measurePosition);
688
+ const beats = Math.floor((measurePosition - bars) * 4);
689
+ const label = `${bars}${beats ? `.${beats}` : ""}`;
690
+ return {
691
+ index,
692
+ ticks,
693
+ isHighlighted: Math.ceil((index + 1) * selectedGridDivisorTicks() / measureTicks()) % 2 === 0,
694
+ hasHighlightedBorder: index * gridDivisorTicks() % selectedGridDivisorTicks() === 0,
695
+ showLabel: index * selectedGridDivisorTicks() / measureTicks() % 2 === 0,
696
+ virtualDimensions: horizontalViewPort().calculatePixelDimensions(ticks, gridDivisorTicks()),
697
+ label
698
+ };
699
+ });
671
700
  });
701
+ return gridArray;
702
+ };
703
+
704
+ const _tmpl$$5 = /*#__PURE__*/web.template(`<div></div>`, 2);
705
+ const PianoRollGrid = () => {
706
+ const context = usePianoRollContext();
707
+ const verticalViewPort = solidJs.createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
708
+ const horizontalViewPort = solidJs.createMemo(() => useViewPortDimension("horizontal"));
709
+ const gridArray = usePianoRollGrid();
672
710
  return (() => {
673
- const _el$ = _tmpl$$4.cloneNode(true);
711
+ const _el$ = _tmpl$$5.cloneNode(true);
674
712
  web.insert(_el$, web.createComponent(solidJs.Index, {
675
713
  get each() {
676
714
  return gridArray();
677
715
  },
678
716
  children: entry => {
679
- const virtualDimensions = solidJs.createMemo(() => horizontalViewPort().calculatePixelDimensions(entry().ticks, gridDivisorTicks()));
680
717
  return web.createComponent(solidJs.Show, {
681
718
  get when() {
682
- return virtualDimensions().size > 0;
719
+ return horizontalViewPort().isVisible(entry().virtualDimensions);
683
720
  },
684
721
  get children() {
685
- const _el$2 = _tmpl$$4.cloneNode(true);
722
+ const _el$2 = _tmpl$$5.cloneNode(true);
686
723
  web.effect(_p$ => {
687
- const _v$ = styles$1["PianoRollGrid-Time"],
688
- _v$2 = Math.ceil((entry().index + 1 * selectedGridDivisorTicks()) / measureTicks()) % 2 === 0 ? "#ddd" : "#ccc",
689
- _v$3 = `${virtualDimensions().offset}px`,
690
- _v$4 = `${virtualDimensions().size}px`,
691
- _v$5 = entry().index * gridDivisorTicks() % selectedGridDivisorTicks() === 0 ? "gray" : "#bbb";
692
- _v$ !== _p$._v$ && web.className(_el$2, _p$._v$ = _v$);
693
- _v$2 !== _p$._v$2 && _el$2.style.setProperty("background", _p$._v$2 = _v$2);
694
- _v$3 !== _p$._v$3 && _el$2.style.setProperty("left", _p$._v$3 = _v$3);
695
- _v$4 !== _p$._v$4 && _el$2.style.setProperty("width", _p$._v$4 = _v$4);
696
- _v$5 !== _p$._v$5 && _el$2.style.setProperty("border-left-color", _p$._v$5 = _v$5);
724
+ const _v$ = {
725
+ [styles$2["PianoRollGrid-Time"]]: true,
726
+ [styles$2["Highlighted"]]: entry().isHighlighted,
727
+ [styles$2["HighlightedBorder"]]: entry().hasHighlightedBorder
728
+ },
729
+ _v$2 = `${entry().virtualDimensions.offset}px`,
730
+ _v$3 = `${entry().virtualDimensions.size}px`;
731
+ _p$._v$ = web.classList(_el$2, _v$, _p$._v$);
732
+ _v$2 !== _p$._v$2 && _el$2.style.setProperty("left", _p$._v$2 = _v$2);
733
+ _v$3 !== _p$._v$3 && _el$2.style.setProperty("width", _p$._v$3 = _v$3);
697
734
  return _p$;
698
735
  }, {
699
736
  _v$: undefined,
700
737
  _v$2: undefined,
701
- _v$3: undefined,
702
- _v$4: undefined,
703
- _v$5: undefined
738
+ _v$3: undefined
704
739
  });
705
740
  return _el$2;
706
741
  }
@@ -718,29 +753,27 @@ const PianoRollGrid = () => {
718
753
  const virtualDimensions = solidJs.createMemo(() => verticalViewPort().calculatePixelDimensions(127 - key().number, 1));
719
754
  return web.createComponent(solidJs.Show, {
720
755
  get when() {
721
- return virtualDimensions().size > 0;
756
+ return verticalViewPort().isVisible(virtualDimensions());
722
757
  },
723
758
  get children() {
724
- const _el$3 = _tmpl$$4.cloneNode(true);
725
- _el$3.style.setProperty("width", "100%");
759
+ const _el$3 = _tmpl$$5.cloneNode(true);
726
760
  web.effect(_p$ => {
727
- const _v$6 = styles$1["PianoRollGrid-Row"],
728
- _v$7 = `${virtualDimensions().offset}px`,
729
- _v$8 = `${virtualDimensions().size}px`,
730
- _v$9 = key().isBlack ? "rgba(0,0,0,0.2)" : "none",
731
- _v$10 = `${!key().isBlack && !blackKeys.includes((key().number + 1) % 12) ? "0.1px" : 0} 1px ${!key().isBlack && !blackKeys.includes((key().number - 1) % 12) ? "0.1px" : 0} 0`;
732
- _v$6 !== _p$._v$6 && web.className(_el$3, _p$._v$6 = _v$6);
733
- _v$7 !== _p$._v$7 && _el$3.style.setProperty("top", _p$._v$7 = _v$7);
734
- _v$8 !== _p$._v$8 && _el$3.style.setProperty("height", _p$._v$8 = _v$8);
735
- _v$9 !== _p$._v$9 && _el$3.style.setProperty("background-color", _p$._v$9 = _v$9);
736
- _v$10 !== _p$._v$10 && _el$3.style.setProperty("border-width", _p$._v$10 = _v$10);
761
+ const _v$4 = {
762
+ [styles$2["PianoRollGrid-Row"]]: true,
763
+ [styles$2["Key"]]: true,
764
+ [styles$2["IsDark"]]: key().isBlack,
765
+ [styles$2["IsBlackAndNextIsWhite"]]: !key().isBlack && !blackKeys.includes((key().number + 1) % 12)
766
+ },
767
+ _v$5 = `${virtualDimensions().offset}px`,
768
+ _v$6 = `${virtualDimensions().size}px`;
769
+ _p$._v$4 = web.classList(_el$3, _v$4, _p$._v$4);
770
+ _v$5 !== _p$._v$5 && _el$3.style.setProperty("top", _p$._v$5 = _v$5);
771
+ _v$6 !== _p$._v$6 && _el$3.style.setProperty("height", _p$._v$6 = _v$6);
737
772
  return _p$;
738
773
  }, {
739
- _v$6: undefined,
740
- _v$7: undefined,
741
- _v$8: undefined,
742
- _v$9: undefined,
743
- _v$10: undefined
774
+ _v$4: undefined,
775
+ _v$5: undefined,
776
+ _v$6: undefined
744
777
  });
745
778
  return _el$3;
746
779
  }
@@ -762,27 +795,25 @@ const PianoRollGrid = () => {
762
795
  const virtualDimensions = solidJs.createMemo(() => verticalViewPort().calculatePixelDimensions(index(), 1));
763
796
  return web.createComponent(solidJs.Show, {
764
797
  get when() {
765
- return virtualDimensions().size > 0;
798
+ return verticalViewPort().isVisible(virtualDimensions());
766
799
  },
767
800
  get children() {
768
- const _el$4 = _tmpl$$4.cloneNode(true);
769
- _el$4.style.setProperty("width", "100%");
770
- _el$4.style.setProperty("border-width", "0");
801
+ const _el$4 = _tmpl$$5.cloneNode(true);
771
802
  web.effect(_p$ => {
772
- const _v$11 = styles$1["PianoRollGrid-Row"],
773
- _v$12 = `${virtualDimensions().offset}px`,
774
- _v$13 = `${virtualDimensions().size}px`,
775
- _v$14 = index() % 2 === 0 ? "rgba(0,0,0,0.2)" : "none";
776
- _v$11 !== _p$._v$11 && web.className(_el$4, _p$._v$11 = _v$11);
777
- _v$12 !== _p$._v$12 && _el$4.style.setProperty("top", _p$._v$12 = _v$12);
778
- _v$13 !== _p$._v$13 && _el$4.style.setProperty("height", _p$._v$13 = _v$13);
779
- _v$14 !== _p$._v$14 && _el$4.style.setProperty("background-color", _p$._v$14 = _v$14);
803
+ const _v$7 = {
804
+ [styles$2["PianoRollGrid-Row"]]: true,
805
+ [styles$2["IsDark"]]: index() % 2 === 0
806
+ },
807
+ _v$8 = `${virtualDimensions().offset}px`,
808
+ _v$9 = `${virtualDimensions().size}px`;
809
+ _p$._v$7 = web.classList(_el$4, _v$7, _p$._v$7);
810
+ _v$8 !== _p$._v$8 && _el$4.style.setProperty("top", _p$._v$8 = _v$8);
811
+ _v$9 !== _p$._v$9 && _el$4.style.setProperty("height", _p$._v$9 = _v$9);
780
812
  return _p$;
781
813
  }, {
782
- _v$11: undefined,
783
- _v$12: undefined,
784
- _v$13: undefined,
785
- _v$14: undefined
814
+ _v$7: undefined,
815
+ _v$8: undefined,
816
+ _v$9: undefined
786
817
  });
787
818
  return _el$4;
788
819
  }
@@ -791,47 +822,19 @@ const PianoRollGrid = () => {
791
822
  });
792
823
  }
793
824
  }), null);
794
- web.effect(() => web.className(_el$, styles$1.PianoRollGrid));
825
+ web.effect(() => web.className(_el$, styles$2.PianoRollGrid));
795
826
  return _el$;
796
827
  })();
797
828
  };
798
829
 
799
- const defaultRect = {
800
- left: 0,
801
- width: 0,
802
- top: 0,
803
- height: 0,
804
- bottom: 0,
805
- right: 0,
806
- x: 0,
807
- y: 0
808
- };
809
- function useBoundingClientRect(containerRef) {
810
- const [boundingClientRect, setBoundingClientRect] = solidJs.createSignal(defaultRect);
811
- solidJs.createEffect(() => {
812
- const container = containerRef();
813
- if (!container) return;
814
- const updateBoundingClientRect = () => {
815
- setBoundingClientRect(container.getBoundingClientRect() ?? defaultRect);
816
- };
817
- const resizeObserver = new ResizeObserver(updateBoundingClientRect);
818
- resizeObserver.observe(container);
819
- updateBoundingClientRect();
820
- return () => {
821
- resizeObserver.disconnect();
822
- };
823
- });
824
- return boundingClientRect;
825
- }
826
-
827
- const _tmpl$$3 = /*#__PURE__*/web.template(`<input step="0.01">`, 1);
830
+ const _tmpl$$4 = /*#__PURE__*/web.template(`<input step="0.01">`, 1);
828
831
  const ZoomSliderControl = props => {
829
832
  const propsWithDefaults = solidJs.mergeProps({
830
833
  orientation: "horizontal"
831
834
  }, props);
832
835
  const dimension = solidJs.createMemo(() => useViewPortDimension(props.dimensionName ?? propsWithDefaults.orientation));
833
836
  return (() => {
834
- const _el$ = _tmpl$$3.cloneNode(true);
837
+ const _el$ = _tmpl$$4.cloneNode(true);
835
838
  web.spread(_el$, web.mergeProps({
836
839
  get min() {
837
840
  return dimension().minZoom;
@@ -843,7 +846,10 @@ const ZoomSliderControl = props => {
843
846
  get value() {
844
847
  return dimension().zoom;
845
848
  },
846
- "onInput": event => dimension().onZoomChange?.(event.currentTarget.valueAsNumber),
849
+ "onInput": event => {
850
+ const value = event.currentTarget.valueAsNumber;
851
+ dimension().onZoomChange?.(value);
852
+ },
847
853
  "type": "range"
848
854
  }, () => ({
849
855
  orient: propsWithDefaults.orientation
@@ -873,17 +879,17 @@ const ZoomSliderControl = props => {
873
879
  })();
874
880
  };
875
881
 
876
- var css_248z = ".PianoRollTrackList-module_PianoRollTrackList__-sDf0 {\n position: relative;\n height: 100%;\n flex: 1;\n}\n\n.PianoRollTrackList-module_Track__mZP1K {\n border-width: 0px;\n position: absolute;\n box-sizing: border-box;\n width: 100%;\n border-color: #000;\n border-style: solid;\n border-right-width: 1px;\n border-bottom-width: 1px;\n cursor: \"pointer\";\n background: \"lightgrey\";\n}\n.PianoRollTrackList-module_Track__mZP1K.PianoRollTrackList-module_selected__0b-mf {\n background: \"gray\";\n}";
877
- var styles = {"PianoRollTrackList":"PianoRollTrackList-module_PianoRollTrackList__-sDf0","Track":"PianoRollTrackList-module_Track__mZP1K","selected":"PianoRollTrackList-module_selected__0b-mf"};
878
- styleInject(css_248z);
882
+ var css_248z$1 = ".PianoRollTrackList-module_PianoRollTrackList__-sDf0 {\n position: relative;\n height: 100%;\n flex: 1;\n}\n\n.PianoRollTrackList-module_Track__mZP1K {\n border-width: 0px;\n position: absolute;\n box-sizing: border-box;\n width: 100%;\n border-color: #000;\n border-style: solid;\n border-right-width: 1px;\n border-bottom-width: 1px;\n padding: 2px;\n cursor: pointer;\n background: lightgrey;\n}\n.PianoRollTrackList-module_Track__mZP1K.PianoRollTrackList-module_selected__0b-mf {\n background: gray;\n}";
883
+ var styles$1 = {"PianoRollTrackList":"PianoRollTrackList-module_PianoRollTrackList__-sDf0","Track":"PianoRollTrackList-module_Track__mZP1K","selected":"PianoRollTrackList-module_selected__0b-mf"};
884
+ styleInject(css_248z$1);
879
885
 
880
- const _tmpl$$2 = /*#__PURE__*/web.template(`<div></div>`, 2),
886
+ const _tmpl$$3 = /*#__PURE__*/web.template(`<div></div>`, 2),
881
887
  _tmpl$2$1 = /*#__PURE__*/web.template(`<div> </div>`, 2);
882
888
  const PianoRollTrackList = () => {
883
889
  const viewPort = solidJs.createMemo(() => useViewPortDimension("verticalTracks"));
884
890
  const context = usePianoRollContext();
885
891
  return (() => {
886
- const _el$ = _tmpl$$2.cloneNode(true);
892
+ const _el$ = _tmpl$$3.cloneNode(true);
887
893
  web.insert(_el$, web.createComponent(solidJs.Index, {
888
894
  get each() {
889
895
  return context.tracks;
@@ -902,8 +908,8 @@ const PianoRollTrackList = () => {
902
908
  web.insert(_el$2, () => track().name || "[unnamed track]", null);
903
909
  web.effect(_p$ => {
904
910
  const _v$ = {
905
- [styles["Track"]]: true,
906
- [styles["selected"]]: index === context.selectedTrackIndex
911
+ [styles$1["Track"]]: true,
912
+ [styles$1["selected"]]: index === context.selectedTrackIndex
907
913
  },
908
914
  _v$2 = track().name,
909
915
  _v$3 = `${virtualDimensions().offset}px`,
@@ -924,80 +930,214 @@ const PianoRollTrackList = () => {
924
930
  });
925
931
  }
926
932
  }));
927
- web.effect(() => web.className(_el$, styles.PianoRollTrackList));
933
+ web.effect(() => web.className(_el$, styles$1.PianoRollTrackList));
928
934
  return _el$;
929
935
  })();
930
936
  };
931
937
  web.delegateEvents(["click"]);
932
938
 
933
- const _tmpl$$1 = /*#__PURE__*/web.template(`<div><div></div></div>`, 4),
934
- _tmpl$2 = /*#__PURE__*/web.template(`<div></div>`, 2);
939
+ const PianoRollScrollZoomViewPort = props => {
940
+ const zoomFactor = 500;
941
+ const context = usePianoRollContext();
942
+ return web.createComponent(ScrollZoomViewPort, {
943
+ dimensions: {
944
+ horizontal: () => ({
945
+ pixelOffset: context.notesScrollerClientRect.left,
946
+ pixelSize: context.notesScrollerClientRect.width,
947
+ position: context.position,
948
+ range: context.duration,
949
+ zoom: context.zoom * (zoomFactor / context.notesScrollerClientRect.width),
950
+ onPositionChange: context.onPositionChange,
951
+ onZoomChange: zoom => context.onZoomChange?.(zoom / (zoomFactor / context.notesScrollerClientRect.width)),
952
+ minZoom: 1,
953
+ maxZoom: 500
954
+ }),
955
+ vertical: () => ({
956
+ pixelOffset: context.notesScrollerClientRect.top,
957
+ pixelSize: context.notesScrollerClientRect.height,
958
+ position: context.verticalPosition,
959
+ range: 128,
960
+ zoom: context.verticalZoom * (zoomFactor / context.notesScrollerClientRect.height),
961
+ onPositionChange: context.onVerticalPositionChange,
962
+ onZoomChange: verticalZoom => context.onVerticalZoomChange?.(verticalZoom / (zoomFactor / context.notesScrollerClientRect.height)),
963
+ minZoom: 1,
964
+ maxZoom: 10
965
+ }),
966
+ horizontalTracks: () => ({
967
+ pixelOffset: 0,
968
+ pixelSize: context.tracksScrollerClientRect.width
969
+ }),
970
+ verticalTracks: () => ({
971
+ pixelOffset: context.tracksScrollerClientRect.top,
972
+ pixelSize: context.tracksScrollerClientRect.height,
973
+ position: context.verticalTrackPosition,
974
+ range: context.tracks.length,
975
+ zoom: context.verticalTrackZoom * (zoomFactor / context.tracksScrollerClientRect.height),
976
+ onPositionChange: context.onVerticalTrackPositionChange,
977
+ onZoomChange: verticalTrackZoom => context.onVerticalTrackZoomChange?.(verticalTrackZoom / (zoomFactor / context.tracksScrollerClientRect.height)),
978
+ minZoom: 0.8,
979
+ maxZoom: 3
980
+ }),
981
+ horizontalKeys: () => ({
982
+ pixelSize: 60
983
+ })
984
+ },
985
+ get children() {
986
+ return props.children;
987
+ }
988
+ });
989
+ };
990
+
991
+ const defaultRect = {
992
+ left: 0,
993
+ width: 0,
994
+ top: 0,
995
+ height: 0,
996
+ bottom: 0,
997
+ right: 0,
998
+ x: 0,
999
+ y: 0
1000
+ };
1001
+ function useBoundingClientRect(containerRef) {
1002
+ const [boundingClientRect, setBoundingClientRect] = solidJs.createSignal(defaultRect);
1003
+ solidJs.createEffect(() => {
1004
+ const container = containerRef();
1005
+ if (!container) return;
1006
+ const updateBoundingClientRect = () => {
1007
+ setBoundingClientRect(container.getBoundingClientRect() ?? defaultRect);
1008
+ };
1009
+ const resizeObserver = new ResizeObserver(updateBoundingClientRect);
1010
+ resizeObserver.observe(container);
1011
+ updateBoundingClientRect();
1012
+ return () => {
1013
+ resizeObserver.disconnect();
1014
+ };
1015
+ });
1016
+ return boundingClientRect;
1017
+ }
1018
+
1019
+ const PianoRollNotesScroller = props => {
1020
+ const context = usePianoRollContext();
1021
+ const [ref, setRef] = solidJs.createSignal();
1022
+ const clientRect = useBoundingClientRect(ref);
1023
+ solidJs.createEffect(() => {
1024
+ context.onNotesScrollerClientRectChange(clientRect());
1025
+ });
1026
+ return web.createComponent(ScrollZoomContainer, {
1027
+ ref: setRef,
1028
+ get verticalDimensionName() {
1029
+ return context.mode === "keys" ? "vertical" : "verticalTracks";
1030
+ },
1031
+ get children() {
1032
+ return props.children;
1033
+ }
1034
+ });
1035
+ };
1036
+
1037
+ const PianoRollTrackListScroller = props => {
1038
+ const context = usePianoRollContext();
1039
+ const [ref, setRef] = solidJs.createSignal();
1040
+ const clientRect = useBoundingClientRect(ref);
1041
+ solidJs.createEffect(() => {
1042
+ context.onTracksScrollerClientRectChange(clientRect());
1043
+ });
1044
+ return web.createComponent(ScrollZoomContainer, {
1045
+ ref: setRef,
1046
+ horizontalDimensionName: "horizontalTracks",
1047
+ verticalDimensionName: "verticalTracks",
1048
+ get showScrollbar() {
1049
+ return context.mode === "keys";
1050
+ },
1051
+ get children() {
1052
+ return props.children;
1053
+ }
1054
+ });
1055
+ };
1056
+
1057
+ var css_248z = ".PianoRollScale-module_PianoRollScale__5wGRm {\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.PianoRollScale-module_PianoRollScale-Time__03hGQ {\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 border-left-color: x#666;\n border-bottom-color: #333;\n border-bottom-style: solid;\n border-bottom-width: 0.5px;\n background: #777;\n display: flex;\n align-items: center;\n}\n\n.PianoRollScale-module_PianoRollScale-Label__aoRi6 {\n position: absolute;\n z-index: 1;\n color: #ccc;\n margin-left: 3px;\n font-size: 0.8em;\n}\n\n.PianoRollScale-module_PianoRollScale-Time__03hGQ.PianoRollScale-module_Highlighted__ziWn5 {\n background: #666;\n}\n\n.PianoRollScale-module_PianoRollScale-Time__03hGQ.PianoRollScale-module_HighlightedBorder__-OoZE {\n border-left-color: #111;\n}\n";
1058
+ var styles = {"PianoRollScale":"PianoRollScale-module_PianoRollScale__5wGRm","PianoRollScale-Time":"PianoRollScale-module_PianoRollScale-Time__03hGQ","PianoRollScale-Label":"PianoRollScale-module_PianoRollScale-Label__aoRi6","Highlighted":"PianoRollScale-module_Highlighted__ziWn5","HighlightedBorder":"PianoRollScale-module_HighlightedBorder__-OoZE"};
1059
+ styleInject(css_248z);
1060
+
1061
+ const _tmpl$$2 = /*#__PURE__*/web.template(`<div></div>`, 2);
1062
+ const PianoRollScale = () => {
1063
+ const horizontalViewPort = solidJs.createMemo(() => useViewPortDimension("horizontal"));
1064
+ const grid = usePianoRollGrid();
1065
+ return (() => {
1066
+ const _el$ = _tmpl$$2.cloneNode(true);
1067
+ web.insert(_el$, web.createComponent(solidJs.Index, {
1068
+ get each() {
1069
+ return grid();
1070
+ },
1071
+ children: entry => {
1072
+ return web.createComponent(solidJs.Show, {
1073
+ get when() {
1074
+ return horizontalViewPort().isVisible(entry().virtualDimensions);
1075
+ },
1076
+ get children() {
1077
+ const _el$2 = _tmpl$$2.cloneNode(true);
1078
+ web.insert(_el$2, web.createComponent(solidJs.Show, {
1079
+ get when() {
1080
+ return entry().showLabel;
1081
+ },
1082
+ get children() {
1083
+ const _el$3 = _tmpl$$2.cloneNode(true);
1084
+ web.insert(_el$3, () => entry().label);
1085
+ web.effect(() => web.className(_el$3, styles["PianoRollScale-Label"]));
1086
+ return _el$3;
1087
+ }
1088
+ }));
1089
+ web.effect(_p$ => {
1090
+ const _v$ = {
1091
+ [styles["PianoRollScale-Time"]]: true,
1092
+ [styles["Highlighted"]]: entry().isHighlighted,
1093
+ [styles["HighlightedBorder"]]: entry().hasHighlightedBorder
1094
+ },
1095
+ _v$2 = `${entry().virtualDimensions.offset}px`,
1096
+ _v$3 = `${entry().virtualDimensions.size}px`;
1097
+ _p$._v$ = web.classList(_el$2, _v$, _p$._v$);
1098
+ _v$2 !== _p$._v$2 && _el$2.style.setProperty("left", _p$._v$2 = _v$2);
1099
+ _v$3 !== _p$._v$3 && _el$2.style.setProperty("width", _p$._v$3 = _v$3);
1100
+ return _p$;
1101
+ }, {
1102
+ _v$: undefined,
1103
+ _v$2: undefined,
1104
+ _v$3: undefined
1105
+ });
1106
+ return _el$2;
1107
+ }
1108
+ });
1109
+ }
1110
+ }));
1111
+ web.effect(() => web.className(_el$, styles.PianoRollScale));
1112
+ return _el$;
1113
+ })();
1114
+ };
1115
+
1116
+ const _tmpl$$1 = /*#__PURE__*/web.template(`<div><button><div></div></button></div>`, 6),
1117
+ _tmpl$2 = /*#__PURE__*/web.template(`<div><div><div></div></div><div><div></div></div></div>`, 10),
1118
+ _tmpl$3 = /*#__PURE__*/web.template(`<div></div>`, 2);
935
1119
  const PianoRoll = allProps => {
936
1120
  const propsWithDefaults = solidJs.mergeProps({
937
1121
  showAllTracks: false
938
1122
  }, allProps);
939
1123
  const [context, divProps] = splitContextProps(propsWithDefaults);
940
- const [notesScrollerRef, setNotesScrollerRef] = solidJs.createSignal();
941
- const [tracksScrollerRef, setTracksScrollerRef] = solidJs.createSignal();
942
- const notesScrollerClientRect = useBoundingClientRect(notesScrollerRef);
943
- const tracksScrollerClientRect = useBoundingClientRect(tracksScrollerRef);
944
- const zoomFactor = 500;
945
1124
  return web.createComponent(PianoRollContextProvider, {
946
1125
  value: context,
947
1126
  get children() {
948
- const _el$ = _tmpl$2.cloneNode(true);
1127
+ const _el$ = _tmpl$3.cloneNode(true);
949
1128
  web.spread(_el$, web.mergeProps(divProps, {
950
1129
  get ["class"]() {
951
- return styles$5.PianoRoll;
1130
+ return styles$6.PianoRoll;
952
1131
  }
953
1132
  }), false, true);
954
- web.insert(_el$, web.createComponent(ScrollZoomViewPort, {
955
- dimensions: {
956
- horizontal: () => ({
957
- pixelOffset: notesScrollerClientRect().left,
958
- pixelSize: notesScrollerClientRect().width,
959
- position: context.position,
960
- range: context.duration,
961
- zoom: context.zoom * (zoomFactor / notesScrollerClientRect().width),
962
- onPositionChange: context.onPositionChange,
963
- onZoomChange: zoom => context.onZoomChange?.(zoom / (zoomFactor / notesScrollerClientRect().width)),
964
- minZoom: 1,
965
- maxZoom: 500
966
- }),
967
- vertical: () => ({
968
- pixelOffset: notesScrollerClientRect().top,
969
- pixelSize: notesScrollerClientRect().height,
970
- position: context.verticalPosition,
971
- range: 128,
972
- zoom: context.verticalZoom * (zoomFactor / notesScrollerClientRect().height),
973
- onPositionChange: context.onVerticalPositionChange,
974
- onZoomChange: verticalZoom => context.onVerticalZoomChange?.(verticalZoom / (zoomFactor / notesScrollerClientRect().height)),
975
- minZoom: 1,
976
- maxZoom: 10
977
- }),
978
- horizontalTracks: () => ({
979
- pixelOffset: 0,
980
- pixelSize: tracksScrollerClientRect().width
981
- }),
982
- verticalTracks: () => ({
983
- pixelOffset: tracksScrollerClientRect().top,
984
- pixelSize: tracksScrollerClientRect().height,
985
- position: context.verticalTrackPosition,
986
- range: context.tracks.length,
987
- zoom: context.verticalTrackZoom * (zoomFactor / tracksScrollerClientRect().height),
988
- onPositionChange: context.onVerticalTrackPositionChange,
989
- onZoomChange: verticalTrackZoom => context.onVerticalTrackZoomChange?.(verticalTrackZoom / (zoomFactor / tracksScrollerClientRect().height)),
990
- minZoom: 0.8,
991
- maxZoom: 3
992
- }),
993
- horizontalKeys: () => ({
994
- pixelSize: 60
995
- })
996
- },
1133
+ web.insert(_el$, web.createComponent(PianoRollScrollZoomViewPort, {
997
1134
  get children() {
998
1135
  return [(() => {
999
- const _el$2 = _tmpl$$1.cloneNode(true),
1000
- _el$3 = _el$2.firstChild;
1136
+ const _el$2 = _tmpl$2.cloneNode(true),
1137
+ _el$3 = _el$2.firstChild,
1138
+ _el$7 = _el$3.firstChild,
1139
+ _el$8 = _el$3.nextSibling,
1140
+ _el$9 = _el$8.firstChild;
1001
1141
  web.insert(_el$2, web.createComponent(ZoomSliderControl, {
1002
1142
  orientation: "vertical",
1003
1143
  dimensionName: "verticalTracks"
@@ -1007,20 +1147,36 @@ const PianoRoll = allProps => {
1007
1147
  return context.showTrackList;
1008
1148
  },
1009
1149
  get children() {
1010
- return web.createComponent(ScrollZoomContainer, {
1011
- ref: setTracksScrollerRef,
1012
- horizontalDimensionName: "horizontalTracks",
1013
- verticalDimensionName: "verticalTracks",
1014
- get showScrollbar() {
1015
- return context.mode === "keys";
1016
- },
1150
+ const _el$4 = _tmpl$$1.cloneNode(true),
1151
+ _el$5 = _el$4.firstChild,
1152
+ _el$6 = _el$5.firstChild;
1153
+ _el$4.style.setProperty("height", "30px");
1154
+ _el$5.$$click = () => context.onModeChange(context.mode === "keys" ? "tracks" : "keys");
1155
+ _el$5.style.setProperty("font-size", "16px");
1156
+ _el$5.style.setProperty("line-height", "16px");
1157
+ _el$5.style.setProperty("cursor", "pointer");
1158
+ _el$5.style.setProperty("overflow", "hidden");
1159
+ web.insert(_el$6, () => context.mode === "keys" ? "≡" : "🎹");
1160
+ web.effect(() => web.setAttribute(_el$5, "title", context.mode === "keys" ? "Tracks Mode" : "Keys Mode"));
1161
+ return _el$4;
1162
+ }
1163
+ }), _el$7);
1164
+ _el$7.style.setProperty("flex", "1");
1165
+ _el$7.style.setProperty("display", "flex");
1166
+ _el$7.style.setProperty("overflow", "hidden");
1167
+ web.insert(_el$7, web.createComponent(solidJs.Show, {
1168
+ get when() {
1169
+ return context.showTrackList;
1170
+ },
1171
+ get children() {
1172
+ return web.createComponent(PianoRollTrackListScroller, {
1017
1173
  get children() {
1018
1174
  return web.createComponent(PianoRollTrackList, {});
1019
1175
  }
1020
1176
  });
1021
1177
  }
1022
1178
  }), null);
1023
- web.insert(_el$3, web.createComponent(solidJs.Show, {
1179
+ web.insert(_el$7, web.createComponent(solidJs.Show, {
1024
1180
  get when() {
1025
1181
  return context.mode === "keys";
1026
1182
  },
@@ -1028,11 +1184,14 @@ const PianoRoll = allProps => {
1028
1184
  return web.createComponent(PianoRollKeys, {});
1029
1185
  }
1030
1186
  }), null);
1031
- web.insert(_el$2, web.createComponent(ScrollZoomContainer, {
1032
- ref: setNotesScrollerRef,
1033
- get verticalDimensionName() {
1034
- return context.mode === "keys" ? "vertical" : "verticalTracks";
1035
- },
1187
+ _el$8.style.setProperty("width", "100%");
1188
+ _el$8.style.setProperty("display", "flex");
1189
+ _el$8.style.setProperty("height", "100%");
1190
+ _el$8.style.setProperty("flex-direction", "column");
1191
+ _el$8.style.setProperty("overflow", "hidden");
1192
+ _el$9.style.setProperty("height", "30px");
1193
+ web.insert(_el$9, web.createComponent(PianoRollScale, {}));
1194
+ web.insert(_el$8, web.createComponent(PianoRollNotesScroller, {
1036
1195
  get children() {
1037
1196
  return [web.memo(() => allProps.children), web.createComponent(PianoRollGrid, {}), web.createComponent(PianoRollNotes, {})];
1038
1197
  }
@@ -1044,10 +1203,13 @@ const PianoRoll = allProps => {
1044
1203
  }
1045
1204
  }), null);
1046
1205
  web.effect(_p$ => {
1047
- const _v$ = styles$5.PianoRollContainer,
1048
- _v$2 = styles$5.PianoRollLeftColumn;
1206
+ const _v$ = styles$6.PianoRollContainer,
1207
+ _v$2 = {
1208
+ [styles$6.PianoRollLeftColumn]: true,
1209
+ [styles$6.showTrackList]: context.showTrackList
1210
+ };
1049
1211
  _v$ !== _p$._v$ && web.className(_el$2, _p$._v$ = _v$);
1050
- _v$2 !== _p$._v$2 && web.className(_el$3, _p$._v$2 = _v$2);
1212
+ _p$._v$2 = web.classList(_el$3, _v$2, _p$._v$2);
1051
1213
  return _p$;
1052
1214
  }, {
1053
1215
  _v$: undefined,
@@ -1058,7 +1220,7 @@ const PianoRoll = allProps => {
1058
1220
  orientation: "horizontal",
1059
1221
  get style() {
1060
1222
  return {
1061
- "margin-left": `${tracksScrollerClientRect().width + 24}px`,
1223
+ "margin-left": `${context.tracksScrollerClientRect.width + 24}px`,
1062
1224
  "margin-right": "24px"
1063
1225
  };
1064
1226
  }
@@ -1069,6 +1231,7 @@ const PianoRoll = allProps => {
1069
1231
  }
1070
1232
  });
1071
1233
  };
1234
+ web.delegateEvents(["click"]);
1072
1235
 
1073
1236
  const _tmpl$ = /*#__PURE__*/web.template(`<div class="PlayHead"></div>`, 2);
1074
1237
  const PlayHead = allProps => {