solid-pianoroll 0.0.13 → 0.0.14

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
@@ -42,11 +42,11 @@ const usePianoRollContext = () => {
42
42
  };
43
43
  const splitContextProps = allProps => solidJs.splitProps(allProps, ["condensed", "duration", "gridDivision", "notes", "position", "ppq", "snapToGrid", "verticalPosition", "verticalZoom", "zoom", "onInsertNote", "onNoteChange", "onPositionChange", "onRemoveNote", "onVerticalPositionChange", "onVerticalZoomChange", "onZoomChange"]);
44
44
 
45
- const _tmpl$$7 = /*#__PURE__*/web.template(`<input max="500" min="1" step="0.01">`, 1);
45
+ const _tmpl$$8 = /*#__PURE__*/web.template(`<input max="500" min="1" step="0.01">`, 1);
46
46
  const HorizontalZoomControl = props => {
47
47
  const context = usePianoRollContext();
48
48
  return (() => {
49
- const _el$ = _tmpl$$7.cloneNode(true);
49
+ const _el$ = _tmpl$$8.cloneNode(true);
50
50
  web.spread(_el$, web.mergeProps(props, {
51
51
  get value() {
52
52
  return context.zoom;
@@ -68,6 +68,7 @@ const HorizontalZoomControl = props => {
68
68
  function createViewPortDimension(getState) {
69
69
  const getStateWithFunctions = () => ({
70
70
  ...getState(),
71
+ calculatePixelOffset,
71
72
  calculatePixelValue,
72
73
  calculatePosition,
73
74
  calculatePixelDimensions,
@@ -140,7 +141,7 @@ var css_248z$2 = ".PianoRollNotes-module_PianoRollNotes__6pF-y {\n position: ab
140
141
  var styles$2 = {"PianoRollNotes":"PianoRollNotes-module_PianoRollNotes__6pF-y","Note":"PianoRollNotes-module_Note__-jxLb","trimStart":"PianoRollNotes-module_trimStart__vuBlj","trimEnd":"PianoRollNotes-module_trimEnd__zPdjr"};
141
142
  styleInject(css_248z$2);
142
143
 
143
- const _tmpl$$6 = /*#__PURE__*/web.template(`<div></div>`, 2);
144
+ const _tmpl$$7 = /*#__PURE__*/web.template(`<div></div>`, 2);
144
145
  const PianoRollNotes = props => {
145
146
  const context = usePianoRollContext();
146
147
  const verticalViewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
@@ -177,7 +178,7 @@ const PianoRollNotes = props => {
177
178
  return noteDragMode ? [styles$2.Note, styles$2[noteDragMode]] : [styles$2.Note];
178
179
  };
179
180
  return (() => {
180
- const _el$ = _tmpl$$6.cloneNode(true);
181
+ const _el$ = _tmpl$$7.cloneNode(true);
181
182
  _el$.$$click = event => {
182
183
  if (newNote()) {
183
184
  setNewNoteIndex(-1);
@@ -223,7 +224,7 @@ const PianoRollNotes = props => {
223
224
  return web.memo(() => !!(verticalViewPort().isVisible(verticalVirtualDimensions()) || context.condensed))() && horizontalViewPort().isVisible(horizontalDimensions());
224
225
  },
225
226
  get children() {
226
- const _el$2 = _tmpl$$6.cloneNode(true);
227
+ const _el$2 = _tmpl$$7.cloneNode(true);
227
228
  _el$2.$$mousedown = event => {
228
229
  event.stopPropagation();
229
230
  setIsDragging(true);
@@ -299,7 +300,7 @@ const PianoRollNotes = props => {
299
300
  };
300
301
  web.delegateEvents(["mousedown", "mousemove", "mouseup", "dblclick", "click"]);
301
302
 
302
- const _tmpl$$5 = /*#__PURE__*/web.template(`<div class="PianoRoll-Scroller"><div><div><div></div></div></div></div>`, 8);
303
+ const _tmpl$$6 = /*#__PURE__*/web.template(`<div class="PianoRoll-Scroller"><div><div><div></div></div></div></div>`, 8);
303
304
  const ScrollContainer = props => {
304
305
  let scrollContentRef;
305
306
  const verticalViewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
@@ -361,7 +362,7 @@ const ScrollContainer = props => {
361
362
  });
362
363
  });
363
364
  return (() => {
364
- const _el$ = _tmpl$$5.cloneNode(true),
365
+ const _el$ = _tmpl$$6.cloneNode(true),
365
366
  _el$2 = _el$.firstChild,
366
367
  _el$3 = _el$2.firstChild,
367
368
  _el$4 = _el$3.firstChild;
@@ -406,11 +407,11 @@ var css_248z$1 = ".PianoRollKeys-module_PianoRollKeys__5vnQ0 {\n position: rela
406
407
  var styles$1 = {"PianoRollKeys":"PianoRollKeys-module_PianoRollKeys__5vnQ0","Key":"PianoRollKeys-module_Key__jybNC","black":"PianoRollKeys-module_black__7rncB","white":"PianoRollKeys-module_white__fR2Lm","whiteAndNextIsWhite":"PianoRollKeys-module_whiteAndNextIsWhite__PN1O8","whiteAndPreviousIsWhite":"PianoRollKeys-module_whiteAndPreviousIsWhite__-fP3q"};
407
408
  styleInject(css_248z$1);
408
409
 
409
- const _tmpl$$4 = /*#__PURE__*/web.template(`<div></div>`, 2);
410
+ const _tmpl$$5 = /*#__PURE__*/web.template(`<div></div>`, 2);
410
411
  const PianoRollKeys = () => {
411
412
  const viewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
412
413
  return (() => {
413
- const _el$ = _tmpl$$4.cloneNode(true);
414
+ const _el$ = _tmpl$$5.cloneNode(true);
414
415
  web.insert(_el$, web.createComponent(solidJs.Index, {
415
416
  each: keys,
416
417
  children: key => {
@@ -420,7 +421,7 @@ const PianoRollKeys = () => {
420
421
  return virtualDimensions().size > 0;
421
422
  },
422
423
  get children() {
423
- const _el$2 = _tmpl$$4.cloneNode(true);
424
+ const _el$2 = _tmpl$$5.cloneNode(true);
424
425
  web.effect(_p$ => {
425
426
  const _v$ = {
426
427
  [styles$1["Key"]]: true,
@@ -469,7 +470,7 @@ var css_248z = ".PianoRollGrid-module_PianoRollGrid__tG119 {\n position: relati
469
470
  var styles = {"PianoRollGrid":"PianoRollGrid-module_PianoRollGrid__tG119","PianoRollGrid-Key":"PianoRollGrid-module_PianoRollGrid-Key__VRbiB","PianoRollGrid-Time":"PianoRollGrid-module_PianoRollGrid-Time__jLz3E"};
470
471
  styleInject(css_248z);
471
472
 
472
- const _tmpl$$3 = /*#__PURE__*/web.template(`<div></div>`, 2);
473
+ const _tmpl$$4 = /*#__PURE__*/web.template(`<div></div>`, 2);
473
474
  const PianoRollGrid = () => {
474
475
  const context = usePianoRollContext();
475
476
  const verticalViewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
@@ -477,10 +478,12 @@ const PianoRollGrid = () => {
477
478
  const measureTicks = solidJs.createMemo(() => context.ppq * 4);
478
479
  const selectedGridDivisorTicks = solidJs.createMemo(() => measureTicks() / context.gridDivision);
479
480
  function calculateVisibleGridDivisorTicks(value) {
480
- if (horizontalViewPort().calculateVisibleRange() / value > 100) {
481
+ const visibleRange = horizontalViewPort().calculateVisibleRange();
482
+ if (visibleRange <= 0) return 0;
483
+ if (visibleRange / value > 100) {
481
484
  return calculateVisibleGridDivisorTicks(value * 2);
482
485
  }
483
- if (horizontalViewPort().calculateVisibleRange() / value < 30) {
486
+ if (visibleRange / value < 30) {
484
487
  return calculateVisibleGridDivisorTicks(value / 2);
485
488
  }
486
489
  return value;
@@ -497,7 +500,7 @@ const PianoRollGrid = () => {
497
500
  }));
498
501
  });
499
502
  return (() => {
500
- const _el$ = _tmpl$$3.cloneNode(true);
503
+ const _el$ = _tmpl$$4.cloneNode(true);
501
504
  web.insert(_el$, web.createComponent(solidJs.Index, {
502
505
  get each() {
503
506
  return gridArray();
@@ -509,7 +512,7 @@ const PianoRollGrid = () => {
509
512
  return virtualDimensions().size > 0;
510
513
  },
511
514
  get children() {
512
- const _el$2 = _tmpl$$3.cloneNode(true);
515
+ const _el$2 = _tmpl$$4.cloneNode(true);
513
516
  web.effect(_p$ => {
514
517
  const _v$ = styles["PianoRollGrid-Time"],
515
518
  _v$2 = Math.ceil((entry().index + 1 * selectedGridDivisorTicks()) / measureTicks()) % 2 === 0 ? "#ddd" : "#ccc",
@@ -548,7 +551,7 @@ const PianoRollGrid = () => {
548
551
  return virtualDimensions().size > 0;
549
552
  },
550
553
  get children() {
551
- const _el$3 = _tmpl$$3.cloneNode(true);
554
+ const _el$3 = _tmpl$$4.cloneNode(true);
552
555
  _el$3.style.setProperty("width", "100%");
553
556
  web.effect(_p$ => {
554
557
  const _v$6 = styles["PianoRollGrid-Key"],
@@ -633,11 +636,11 @@ function useBoundingClientRect(containerRef) {
633
636
  return boundingClientRect;
634
637
  }
635
638
 
636
- const _tmpl$$2 = /*#__PURE__*/web.template(`<input min="1" max="11" step="0.01">`, 1);
639
+ const _tmpl$$3 = /*#__PURE__*/web.template(`<input min="1" max="11" step="0.01">`, 1);
637
640
  const VerticalZoomControl = props => {
638
641
  const context = usePianoRollContext();
639
642
  return (() => {
640
- const _el$ = _tmpl$$2.cloneNode(true);
643
+ const _el$ = _tmpl$$3.cloneNode(true);
641
644
  web.spread(_el$, web.mergeProps(props, {
642
645
  get value() {
643
646
  return context.verticalZoom;
@@ -661,15 +664,21 @@ const VerticalZoomControl = props => {
661
664
  })();
662
665
  };
663
666
 
664
- const _tmpl$$1 = /*#__PURE__*/web.template(`<ul></ul>`, 2),
665
- _tmpl$2 = /*#__PURE__*/web.template(`<div><ul></ul><div><div></div></div></div>`, 8),
666
- _tmpl$3 = /*#__PURE__*/web.template(`<li></li>`, 2);
667
+ const _tmpl$$2 = /*#__PURE__*/web.template(`<div><ul></ul></div>`, 4),
668
+ _tmpl$2 = /*#__PURE__*/web.template(`<ul></ul>`, 2),
669
+ _tmpl$3 = /*#__PURE__*/web.template(`<div><div></div></div>`, 4),
670
+ _tmpl$4 = /*#__PURE__*/web.template(`<div></div>`, 2),
671
+ _tmpl$5 = /*#__PURE__*/web.template(`<li></li>`, 2);
667
672
  const MultiTrackPianoRoll = allProps => {
668
- const condensed = solidJs.createMemo(() => !allProps.selectedTrack);
669
- const [ownProps, restProps] = solidJs.splitProps(allProps, ["tracks", "selectedTrack"]);
673
+ const selectedTrack = solidJs.createMemo(() => allProps.tracks[allProps.selectedTrackIndex]);
674
+ const condensed = solidJs.createMemo(() => !selectedTrack());
675
+ const [ownProps, restProps] = solidJs.splitProps(allProps, ["tracks", "selectedTrackIndex"]);
670
676
  const [contextProps, divProps] = splitContextProps(solidJs.mergeProps(restProps, {
671
677
  notes: [],
672
- condensed: false
678
+ condensed: false,
679
+ onNoteChange: () => undefined,
680
+ onInsertNote: () => -1,
681
+ onRemoveNote: () => undefined
673
682
  }));
674
683
  const [scrollerRef, setScrollerRef] = solidJs.createSignal();
675
684
  const clientRect = useBoundingClientRect(scrollerRef);
@@ -678,179 +687,201 @@ const MultiTrackPianoRoll = allProps => {
678
687
  const maxZoom = solidJs.createMemo(() => 500 * (zoomFactor / clientRect().width));
679
688
  const minVerticalZoom = solidJs.createMemo(() => 1 / (zoomFactor / clientRect().height));
680
689
  const maxVerticalZoom = solidJs.createMemo(() => 10 * (zoomFactor / clientRect().height));
681
- return web.createComponent(PianoRollContextProvider, {
682
- get value() {
683
- return {
684
- ...contextProps
685
- };
686
- },
687
- get children() {
688
- return web.createComponent(ScrollZoomViewPort, {
689
- dimensions: {
690
- horizontal: () => ({
691
- pixelOffset: clientRect().left,
692
- pixelSize: clientRect().width,
693
- position: contextProps.position,
694
- range: contextProps.duration,
695
- zoom: contextProps.zoom * (zoomFactor / clientRect().width),
696
- onPositionChange: contextProps.onPositionChange,
697
- onZoomChange: zoom => contextProps.onZoomChange?.(clamp(zoom / (zoomFactor / clientRect().width), minZoom(), maxZoom()))
698
- }),
699
- vertical: () => ({
700
- pixelOffset: clientRect().top,
701
- pixelSize: clientRect().height,
702
- position: contextProps.verticalPosition,
703
- range: 128,
704
- zoom: contextProps.verticalZoom * (zoomFactor / clientRect().height),
705
- onPositionChange: contextProps.onVerticalPositionChange,
706
- onZoomChange: verticalZoom => contextProps.onVerticalZoomChange?.(clamp(verticalZoom / (zoomFactor / clientRect().height), minVerticalZoom(), maxVerticalZoom()))
707
- })
708
- },
709
- get children() {
710
- const _el$ = _tmpl$2.cloneNode(true),
711
- _el$2 = _el$.firstChild,
712
- _el$3 = _el$2.nextSibling,
713
- _el$4 = _el$3.firstChild;
714
- _el$.style.setProperty("display", "flex");
715
- _el$.style.setProperty("flex", "1");
716
- _el$.style.setProperty("height", "100%");
717
- _el$.style.setProperty("flex-direction", "row");
718
- _el$2.style.setProperty("margin-block-start", "0");
719
- _el$2.style.setProperty("padding-inline-start", "0");
720
- _el$2.style.setProperty("width", "150px");
721
- web.insert(_el$2, web.createComponent(solidJs.Index, {
722
- get each() {
723
- return allProps.tracks;
724
- },
725
- children: track => (() => {
726
- const _el$6 = _tmpl$3.cloneNode(true);
727
- _el$6.$$click = () => {
728
- if (track() === allProps.selectedTrack) {
729
- allProps.onSelectedTrackChange(undefined);
730
- } else {
731
- allProps.onSelectedTrackChange(track());
732
- }
733
- };
734
- _el$6.style.setProperty("width", "150px");
735
- _el$6.style.setProperty("height", "30px");
736
- _el$6.style.setProperty("list-style", "none");
737
- _el$6.style.setProperty("display", "flex");
738
- _el$6.style.setProperty("align-items", "center");
739
- _el$6.style.setProperty("border-top", "1px black solid");
740
- _el$6.style.setProperty("cursor", "pointer");
741
- web.insert(_el$6, () => track().name);
742
- web.effect(() => _el$6.style.setProperty("background", track() === allProps.selectedTrack ? "lightgray" : "none"));
743
- return _el$6;
744
- })()
745
- }));
746
- _el$3.style.setProperty("flex", "1");
747
- web.insert(_el$4, web.createComponent(solidJs.Show, {
748
- get when() {
749
- return !condensed();
750
- },
751
- get children() {
752
- return web.createComponent(PianoRollKeys, {});
753
- }
754
- }), null);
755
- web.insert(_el$4, web.createComponent(ScrollContainer, {
756
- ref: setScrollerRef,
757
- get children() {
758
- const _el$5 = _tmpl$$1.cloneNode(true);
759
- _el$5.style.setProperty("margin", "0");
760
- _el$5.style.setProperty("margin-block-start", "0");
761
- _el$5.style.setProperty("padding-inline-start", "0");
762
- web.insert(_el$5, web.createComponent(solidJs.Index, {
690
+ return (() => {
691
+ const _el$ = _tmpl$4.cloneNode(true);
692
+ web.spread(_el$, web.mergeProps(divProps, {
693
+ get style() {
694
+ return {
695
+ display: "flex",
696
+ flex: 1,
697
+ height: "100%",
698
+ "flex-direction": "row",
699
+ overflow: "hidden",
700
+ ...(typeof divProps.style === "object" && divProps.style)
701
+ };
702
+ }
703
+ }), false, true);
704
+ web.insert(_el$, web.createComponent(PianoRollContextProvider, {
705
+ get value() {
706
+ return {
707
+ ...contextProps
708
+ };
709
+ },
710
+ get children() {
711
+ return web.createComponent(ScrollZoomViewPort, {
712
+ dimensions: {
713
+ horizontal: () => ({
714
+ pixelOffset: clientRect().left,
715
+ pixelSize: clientRect().width,
716
+ position: contextProps.position,
717
+ range: contextProps.duration,
718
+ zoom: contextProps.zoom * (zoomFactor / clientRect().width),
719
+ onPositionChange: contextProps.onPositionChange,
720
+ onZoomChange: zoom => contextProps.onZoomChange?.(clamp(zoom / (zoomFactor / clientRect().width), minZoom(), maxZoom()))
721
+ }),
722
+ vertical: () => ({
723
+ pixelOffset: clientRect().top,
724
+ pixelSize: clientRect().height,
725
+ position: contextProps.verticalPosition,
726
+ range: 128,
727
+ zoom: contextProps.verticalZoom * (zoomFactor / clientRect().height),
728
+ onPositionChange: contextProps.onVerticalPositionChange,
729
+ onZoomChange: verticalZoom => contextProps.onVerticalZoomChange?.(clamp(verticalZoom / (zoomFactor / clientRect().height), minVerticalZoom(), maxVerticalZoom()))
730
+ })
731
+ },
732
+ get children() {
733
+ return [(() => {
734
+ const _el$2 = _tmpl$$2.cloneNode(true),
735
+ _el$3 = _el$2.firstChild;
736
+ _el$2.style.setProperty("width", "250px");
737
+ _el$2.style.setProperty("display", "flex");
738
+ _el$2.style.setProperty("flex-direction", "row");
739
+ _el$3.style.setProperty("margin-block-start", "0");
740
+ _el$3.style.setProperty("padding-inline-start", "0");
741
+ _el$3.style.setProperty("flex", "1");
742
+ _el$3.style.setProperty("position", "relative");
743
+ web.insert(_el$3, web.createComponent(solidJs.Index, {
763
744
  get each() {
764
745
  return allProps.tracks;
765
746
  },
766
- children: track => {
767
- const notes = useNotes();
768
- solidJs.createEffect(() => {
769
- notes.onNotesChange(track().notes);
770
- });
771
- const [context, setContext] = store.createStore({
772
- ...contextProps
773
- });
774
- solidJs.createEffect(() => {
775
- setContext({
776
- ...contextProps,
777
- condensed: condensed(),
778
- notes: notes.notes(),
779
- onNoteChange: notes.onNoteChange,
780
- onInsertNote: notes.onInsertNote,
781
- onRemoveNote: notes.onRemoveNote
782
- });
783
- });
784
- const verticalViewPort = useViewPortDimension("vertical");
785
- return web.createComponent(solidJs.Show, {
786
- get when() {
787
- return condensed() || allProps.selectedTrack === track();
788
- },
789
- get children() {
790
- return web.createComponent(PianoRollContextProvider, {
791
- value: context,
792
- get children() {
793
- const _el$7 = _tmpl$3.cloneNode(true);
794
- _el$7.style.setProperty("display", "flex");
795
- _el$7.style.setProperty("position", "relative");
796
- _el$7.style.setProperty("list-style", "none");
797
- _el$7.style.setProperty("flex-direction", "row");
798
- _el$7.style.setProperty("border-top", "1px black solid");
799
- web.insert(_el$7, web.createComponent(PianoRollNotes, {}), null);
800
- web.insert(_el$7, web.createComponent(PianoRollGrid, {}), null);
801
- web.effect(() => _el$7.style.setProperty("height", condensed() ? "30px" : `${verticalViewPort.pixelSize}px`));
802
- return _el$7;
803
- }
804
- });
747
+ children: (track, noteIndex) => (() => {
748
+ const _el$7 = _tmpl$5.cloneNode(true);
749
+ _el$7.$$click = () => {
750
+ if (noteIndex === allProps.selectedTrackIndex) {
751
+ allProps.onSelectedTrackIndexChange(-1);
752
+ } else {
753
+ allProps.onSelectedTrackIndexChange(noteIndex);
805
754
  }
755
+ };
756
+ _el$7.style.setProperty("width", "100%");
757
+ _el$7.style.setProperty("height", "30px");
758
+ _el$7.style.setProperty("list-style", "none");
759
+ _el$7.style.setProperty("display", "flex");
760
+ _el$7.style.setProperty("align-items", "center");
761
+ _el$7.style.setProperty("border-top", "1px black solid");
762
+ _el$7.style.setProperty("cursor", "pointer");
763
+ web.insert(_el$7, () => track().name);
764
+ web.effect(() => _el$7.style.setProperty("background", noteIndex === allProps.selectedTrackIndex ? "lightgray" : "none"));
765
+ return _el$7;
766
+ })()
767
+ }));
768
+ web.insert(_el$2, web.createComponent(solidJs.Show, {
769
+ get when() {
770
+ return !condensed();
771
+ },
772
+ get children() {
773
+ return web.createComponent(PianoRollKeys, {});
774
+ }
775
+ }), null);
776
+ return _el$2;
777
+ })(), (() => {
778
+ const _el$4 = _tmpl$3.cloneNode(true),
779
+ _el$5 = _el$4.firstChild;
780
+ _el$4.style.setProperty("flex", "1");
781
+ web.insert(_el$5, web.createComponent(ScrollContainer, {
782
+ ref: setScrollerRef,
783
+ get children() {
784
+ return [web.memo(() => allProps.children), (() => {
785
+ const _el$6 = _tmpl$2.cloneNode(true);
786
+ _el$6.style.setProperty("margin", "0");
787
+ _el$6.style.setProperty("margin-block-start", "0");
788
+ _el$6.style.setProperty("padding-inline-start", "0");
789
+ web.insert(_el$6, web.createComponent(solidJs.Index, {
790
+ get each() {
791
+ return allProps.tracks;
792
+ },
793
+ children: (track, trackIndex) => {
794
+ const notes = useNotes();
795
+ solidJs.createEffect(() => {
796
+ notes.onNotesChange(track().notes);
797
+ });
798
+ const [context, setContext] = store.createStore({
799
+ ...contextProps
800
+ });
801
+ solidJs.createEffect(() => {
802
+ setContext({
803
+ ...contextProps,
804
+ condensed: condensed(),
805
+ notes: track()?.notes,
806
+ onNoteChange: (noteIndex, note) => allProps?.onNoteChange?.(trackIndex, noteIndex, note),
807
+ onInsertNote: note => allProps.onInsertNote?.(trackIndex, note) ?? -1,
808
+ onRemoveNote: noteIndex => allProps.onRemoveNote?.(trackIndex, noteIndex)
809
+ });
810
+ });
811
+ const verticalViewPort = useViewPortDimension("vertical");
812
+ return web.createComponent(solidJs.Show, {
813
+ get when() {
814
+ return condensed() || allProps.selectedTrackIndex === trackIndex;
815
+ },
816
+ get children() {
817
+ return web.createComponent(PianoRollContextProvider, {
818
+ value: context,
819
+ get children() {
820
+ const _el$8 = _tmpl$5.cloneNode(true);
821
+ _el$8.style.setProperty("display", "flex");
822
+ _el$8.style.setProperty("position", "relative");
823
+ _el$8.style.setProperty("list-style", "none");
824
+ _el$8.style.setProperty("flex-direction", "row");
825
+ _el$8.style.setProperty("border-top", "1px black solid");
826
+ web.insert(_el$8, web.createComponent(PianoRollNotes, {}), null);
827
+ web.insert(_el$8, web.createComponent(PianoRollGrid, {}), null);
828
+ web.effect(() => _el$8.style.setProperty("height", condensed() ? "30px" : `${verticalViewPort.pixelSize}px`));
829
+ return _el$8;
830
+ }
831
+ });
832
+ }
833
+ });
834
+ }
835
+ }));
836
+ return _el$6;
837
+ })()];
838
+ }
839
+ }), null);
840
+ web.insert(_el$5, web.createComponent(solidJs.Show, {
841
+ get when() {
842
+ return !condensed();
843
+ },
844
+ get children() {
845
+ return web.createComponent(VerticalZoomControl, {
846
+ get value() {
847
+ return contextProps.verticalZoom;
848
+ },
849
+ onInput: event => contextProps.onVerticalZoomChange?.(event.currentTarget.valueAsNumber)
806
850
  });
807
851
  }
808
- }));
809
- return _el$5;
810
- }
811
- }), null);
812
- web.insert(_el$4, web.createComponent(solidJs.Show, {
813
- get when() {
814
- return !condensed();
815
- },
816
- get children() {
817
- return web.createComponent(VerticalZoomControl, {
852
+ }), null);
853
+ web.insert(_el$4, web.createComponent(HorizontalZoomControl, {
854
+ style: {
855
+ width: "100%",
856
+ "margin-left": 0
857
+ },
818
858
  get value() {
819
- return contextProps.verticalZoom;
859
+ return contextProps.zoom;
820
860
  },
821
- onInput: event => contextProps.onVerticalZoomChange?.(event.currentTarget.valueAsNumber)
861
+ onInput: event => contextProps.onZoomChange?.(event.currentTarget.valueAsNumber)
862
+ }), null);
863
+ web.effect(_p$ => {
864
+ const _v$ = styles$3.PianoRoll,
865
+ _v$2 = styles$3.PianoRollContainer;
866
+ _v$ !== _p$._v$ && web.className(_el$4, _p$._v$ = _v$);
867
+ _v$2 !== _p$._v$2 && web.className(_el$5, _p$._v$2 = _v$2);
868
+ return _p$;
869
+ }, {
870
+ _v$: undefined,
871
+ _v$2: undefined
822
872
  });
823
- }
824
- }), null);
825
- web.insert(_el$3, web.createComponent(HorizontalZoomControl, {
826
- style: {
827
- width: "100%",
828
- "margin-left": 0
829
- },
830
- get value() {
831
- return contextProps.zoom;
832
- },
833
- onInput: event => contextProps.onZoomChange?.(event.currentTarget.valueAsNumber)
834
- }), null);
835
- web.effect(_p$ => {
836
- const _v$ = styles$3.PianoRoll,
837
- _v$2 = styles$3.PianoRollContainer;
838
- _v$ !== _p$._v$ && web.className(_el$3, _p$._v$ = _v$);
839
- _v$2 !== _p$._v$2 && web.className(_el$4, _p$._v$2 = _v$2);
840
- return _p$;
841
- }, {
842
- _v$: undefined,
843
- _v$2: undefined
844
- });
845
- return _el$;
846
- }
847
- });
848
- }
849
- });
873
+ return _el$4;
874
+ })()];
875
+ }
876
+ });
877
+ }
878
+ }));
879
+ return _el$;
880
+ })();
850
881
  };
851
882
  web.delegateEvents(["click"]);
852
883
 
853
- const _tmpl$ = /*#__PURE__*/web.template(`<div><div></div></div>`, 4);
884
+ const _tmpl$$1 = /*#__PURE__*/web.template(`<div><div></div></div>`, 4);
854
885
  const PianoRoll = allProps => {
855
886
  const [contextProps, divProps] = splitContextProps(allProps);
856
887
  const [scrollerRef, setScrollerRef] = solidJs.createSignal();
@@ -863,7 +894,7 @@ const PianoRoll = allProps => {
863
894
  return web.createComponent(PianoRollContextProvider, {
864
895
  value: contextProps,
865
896
  get children() {
866
- const _el$ = _tmpl$.cloneNode(true),
897
+ const _el$ = _tmpl$$1.cloneNode(true),
867
898
  _el$2 = _el$.firstChild;
868
899
  web.spread(_el$, web.mergeProps(divProps, {
869
900
  get ["class"]() {
@@ -895,7 +926,7 @@ const PianoRoll = allProps => {
895
926
  return [web.createComponent(PianoRollKeys, {}), web.createComponent(ScrollContainer, {
896
927
  ref: setScrollerRef,
897
928
  get children() {
898
- return [web.createComponent(PianoRollGrid, {}), web.createComponent(PianoRollNotes, {})];
929
+ return [web.memo(() => allProps.children), web.createComponent(PianoRollGrid, {}), web.createComponent(PianoRollNotes, {})];
899
930
  }
900
931
  }), web.createComponent(VerticalZoomControl, {
901
932
  get min() {
@@ -921,6 +952,60 @@ const PianoRoll = allProps => {
921
952
  });
922
953
  };
923
954
 
955
+ const _tmpl$ = /*#__PURE__*/web.template(`<div class="PlayHead"></div>`, 2);
956
+ const PlayHead = allProps => {
957
+ const propsWithDefauls = solidJs.mergeProps({
958
+ playHeadPosition: 0,
959
+ sync: false
960
+ }, allProps);
961
+ const [props, divProps] = solidJs.splitProps(propsWithDefauls, ["playHeadPosition", "sync", "onPlayHeadPositionChange", "onPositionChange"]);
962
+ const viewPort = useViewPortDimension("horizontal");
963
+ solidJs.createEffect(() => {
964
+ if (!props.sync) return;
965
+ const maxPosition = viewPort.range;
966
+ const newPosition = clamp(props.playHeadPosition - viewPort.range / viewPort.zoom / 2, 0, maxPosition);
967
+ props.onPositionChange?.(newPosition);
968
+ });
969
+ const leftPosition = solidJs.createMemo(() => viewPort.calculatePixelOffset(props.playHeadPosition));
970
+ return (() => {
971
+ const _el$ = _tmpl$.cloneNode(true);
972
+ web.spread(_el$, web.mergeProps(divProps, {
973
+ get style() {
974
+ return {
975
+ position: "absolute",
976
+ height: "100%",
977
+ width: "2px",
978
+ left: `${leftPosition()}px`,
979
+ "background-color": "green",
980
+ cursor: "pointer",
981
+ ...(typeof divProps.style === "object" && divProps.style)
982
+ };
983
+ },
984
+ "onMouseDown": event => {
985
+ event.preventDefault();
986
+ event.stopPropagation();
987
+ const handleMouseMove = ({
988
+ movementX
989
+ }) => {
990
+ const {
991
+ parentElement
992
+ } = event.currentTarget;
993
+ if (!parentElement) return;
994
+ const newPosition = viewPort.calculatePosition(leftPosition() + movementX);
995
+ props.onPlayHeadPositionChange?.(newPosition);
996
+ };
997
+ const handleMouseUp = () => {
998
+ window.removeEventListener("mousemove", handleMouseMove);
999
+ window.removeEventListener("mouseup", handleMouseUp);
1000
+ };
1001
+ window.addEventListener("mousemove", handleMouseMove);
1002
+ window.addEventListener("mouseup", handleMouseUp);
1003
+ }
1004
+ }), false, false);
1005
+ return _el$;
1006
+ })();
1007
+ };
1008
+
924
1009
  const usePianoRoll = () => {
925
1010
  const [ppq, onPpqChange] = solidJs.createSignal(120);
926
1011
  const [condensed, onCondensedChange] = solidJs.createSignal(false);
@@ -955,6 +1040,7 @@ const usePianoRoll = () => {
955
1040
 
956
1041
  exports.MultiTrackPianoRoll = MultiTrackPianoRoll;
957
1042
  exports.PianoRoll = PianoRoll;
1043
+ exports.PlayHead = PlayHead;
958
1044
  exports.useNotes = useNotes;
959
1045
  exports.usePianoRoll = usePianoRoll;
960
1046
  //# sourceMappingURL=index.js.map