solid-pianoroll 0.0.12 → 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);
@@ -203,9 +204,11 @@ const PianoRollNotes = props => {
203
204
  const index = insertOrUpdateNote(event);
204
205
  setNewNoteIndex(index);
205
206
  };
206
- _el$.$$mousedown = () => {
207
+ _el$.$$mousedown = event => {
207
208
  console.log("down");
208
209
  setIsMouseDown(true);
210
+ const index = insertOrUpdateNote(event);
211
+ setNewNoteIndex(index);
209
212
  };
210
213
  const _ref$ = props.ref;
211
214
  typeof _ref$ === "function" ? web.use(_ref$, _el$) : props.ref = _el$;
@@ -221,7 +224,7 @@ const PianoRollNotes = props => {
221
224
  return web.memo(() => !!(verticalViewPort().isVisible(verticalVirtualDimensions()) || context.condensed))() && horizontalViewPort().isVisible(horizontalDimensions());
222
225
  },
223
226
  get children() {
224
- const _el$2 = _tmpl$$6.cloneNode(true);
227
+ const _el$2 = _tmpl$$7.cloneNode(true);
225
228
  _el$2.$$mousedown = event => {
226
229
  event.stopPropagation();
227
230
  setIsDragging(true);
@@ -297,7 +300,7 @@ const PianoRollNotes = props => {
297
300
  };
298
301
  web.delegateEvents(["mousedown", "mousemove", "mouseup", "dblclick", "click"]);
299
302
 
300
- 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);
301
304
  const ScrollContainer = props => {
302
305
  let scrollContentRef;
303
306
  const verticalViewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
@@ -359,7 +362,7 @@ const ScrollContainer = props => {
359
362
  });
360
363
  });
361
364
  return (() => {
362
- const _el$ = _tmpl$$5.cloneNode(true),
365
+ const _el$ = _tmpl$$6.cloneNode(true),
363
366
  _el$2 = _el$.firstChild,
364
367
  _el$3 = _el$2.firstChild,
365
368
  _el$4 = _el$3.firstChild;
@@ -404,11 +407,11 @@ var css_248z$1 = ".PianoRollKeys-module_PianoRollKeys__5vnQ0 {\n position: rela
404
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"};
405
408
  styleInject(css_248z$1);
406
409
 
407
- const _tmpl$$4 = /*#__PURE__*/web.template(`<div></div>`, 2);
410
+ const _tmpl$$5 = /*#__PURE__*/web.template(`<div></div>`, 2);
408
411
  const PianoRollKeys = () => {
409
412
  const viewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
410
413
  return (() => {
411
- const _el$ = _tmpl$$4.cloneNode(true);
414
+ const _el$ = _tmpl$$5.cloneNode(true);
412
415
  web.insert(_el$, web.createComponent(solidJs.Index, {
413
416
  each: keys,
414
417
  children: key => {
@@ -418,7 +421,7 @@ const PianoRollKeys = () => {
418
421
  return virtualDimensions().size > 0;
419
422
  },
420
423
  get children() {
421
- const _el$2 = _tmpl$$4.cloneNode(true);
424
+ const _el$2 = _tmpl$$5.cloneNode(true);
422
425
  web.effect(_p$ => {
423
426
  const _v$ = {
424
427
  [styles$1["Key"]]: true,
@@ -467,7 +470,7 @@ var css_248z = ".PianoRollGrid-module_PianoRollGrid__tG119 {\n position: relati
467
470
  var styles = {"PianoRollGrid":"PianoRollGrid-module_PianoRollGrid__tG119","PianoRollGrid-Key":"PianoRollGrid-module_PianoRollGrid-Key__VRbiB","PianoRollGrid-Time":"PianoRollGrid-module_PianoRollGrid-Time__jLz3E"};
468
471
  styleInject(css_248z);
469
472
 
470
- const _tmpl$$3 = /*#__PURE__*/web.template(`<div></div>`, 2);
473
+ const _tmpl$$4 = /*#__PURE__*/web.template(`<div></div>`, 2);
471
474
  const PianoRollGrid = () => {
472
475
  const context = usePianoRollContext();
473
476
  const verticalViewPort = solidJs.createMemo(() => useViewPortDimension("vertical"));
@@ -475,10 +478,12 @@ const PianoRollGrid = () => {
475
478
  const measureTicks = solidJs.createMemo(() => context.ppq * 4);
476
479
  const selectedGridDivisorTicks = solidJs.createMemo(() => measureTicks() / context.gridDivision);
477
480
  function calculateVisibleGridDivisorTicks(value) {
478
- if (horizontalViewPort().calculateVisibleRange() / value > 100) {
481
+ const visibleRange = horizontalViewPort().calculateVisibleRange();
482
+ if (visibleRange <= 0) return 0;
483
+ if (visibleRange / value > 100) {
479
484
  return calculateVisibleGridDivisorTicks(value * 2);
480
485
  }
481
- if (horizontalViewPort().calculateVisibleRange() / value < 30) {
486
+ if (visibleRange / value < 30) {
482
487
  return calculateVisibleGridDivisorTicks(value / 2);
483
488
  }
484
489
  return value;
@@ -495,7 +500,7 @@ const PianoRollGrid = () => {
495
500
  }));
496
501
  });
497
502
  return (() => {
498
- const _el$ = _tmpl$$3.cloneNode(true);
503
+ const _el$ = _tmpl$$4.cloneNode(true);
499
504
  web.insert(_el$, web.createComponent(solidJs.Index, {
500
505
  get each() {
501
506
  return gridArray();
@@ -507,7 +512,7 @@ const PianoRollGrid = () => {
507
512
  return virtualDimensions().size > 0;
508
513
  },
509
514
  get children() {
510
- const _el$2 = _tmpl$$3.cloneNode(true);
515
+ const _el$2 = _tmpl$$4.cloneNode(true);
511
516
  web.effect(_p$ => {
512
517
  const _v$ = styles["PianoRollGrid-Time"],
513
518
  _v$2 = Math.ceil((entry().index + 1 * selectedGridDivisorTicks()) / measureTicks()) % 2 === 0 ? "#ddd" : "#ccc",
@@ -546,7 +551,7 @@ const PianoRollGrid = () => {
546
551
  return virtualDimensions().size > 0;
547
552
  },
548
553
  get children() {
549
- const _el$3 = _tmpl$$3.cloneNode(true);
554
+ const _el$3 = _tmpl$$4.cloneNode(true);
550
555
  _el$3.style.setProperty("width", "100%");
551
556
  web.effect(_p$ => {
552
557
  const _v$6 = styles["PianoRollGrid-Key"],
@@ -631,11 +636,11 @@ function useBoundingClientRect(containerRef) {
631
636
  return boundingClientRect;
632
637
  }
633
638
 
634
- 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);
635
640
  const VerticalZoomControl = props => {
636
641
  const context = usePianoRollContext();
637
642
  return (() => {
638
- const _el$ = _tmpl$$2.cloneNode(true);
643
+ const _el$ = _tmpl$$3.cloneNode(true);
639
644
  web.spread(_el$, web.mergeProps(props, {
640
645
  get value() {
641
646
  return context.verticalZoom;
@@ -659,15 +664,21 @@ const VerticalZoomControl = props => {
659
664
  })();
660
665
  };
661
666
 
662
- const _tmpl$$1 = /*#__PURE__*/web.template(`<ul></ul>`, 2),
663
- _tmpl$2 = /*#__PURE__*/web.template(`<div><ul></ul><div><div></div></div></div>`, 8),
664
- _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);
665
672
  const MultiTrackPianoRoll = allProps => {
666
- const condensed = solidJs.createMemo(() => !allProps.selectedTrack);
667
- 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"]);
668
676
  const [contextProps, divProps] = splitContextProps(solidJs.mergeProps(restProps, {
669
677
  notes: [],
670
- condensed: false
678
+ condensed: false,
679
+ onNoteChange: () => undefined,
680
+ onInsertNote: () => -1,
681
+ onRemoveNote: () => undefined
671
682
  }));
672
683
  const [scrollerRef, setScrollerRef] = solidJs.createSignal();
673
684
  const clientRect = useBoundingClientRect(scrollerRef);
@@ -676,179 +687,201 @@ const MultiTrackPianoRoll = allProps => {
676
687
  const maxZoom = solidJs.createMemo(() => 500 * (zoomFactor / clientRect().width));
677
688
  const minVerticalZoom = solidJs.createMemo(() => 1 / (zoomFactor / clientRect().height));
678
689
  const maxVerticalZoom = solidJs.createMemo(() => 10 * (zoomFactor / clientRect().height));
679
- return web.createComponent(PianoRollContextProvider, {
680
- get value() {
681
- return {
682
- ...contextProps
683
- };
684
- },
685
- get children() {
686
- return web.createComponent(ScrollZoomViewPort, {
687
- dimensions: {
688
- horizontal: () => ({
689
- pixelOffset: clientRect().left,
690
- pixelSize: clientRect().width,
691
- position: contextProps.position,
692
- range: contextProps.duration,
693
- zoom: contextProps.zoom * (zoomFactor / clientRect().width),
694
- onPositionChange: contextProps.onPositionChange,
695
- onZoomChange: zoom => contextProps.onZoomChange?.(clamp(zoom / (zoomFactor / clientRect().width), minZoom(), maxZoom()))
696
- }),
697
- vertical: () => ({
698
- pixelOffset: clientRect().top,
699
- pixelSize: clientRect().height,
700
- position: contextProps.verticalPosition,
701
- range: 128,
702
- zoom: contextProps.verticalZoom * (zoomFactor / clientRect().height),
703
- onPositionChange: contextProps.onVerticalPositionChange,
704
- onZoomChange: verticalZoom => contextProps.onVerticalZoomChange?.(clamp(verticalZoom / (zoomFactor / clientRect().height), minVerticalZoom(), maxVerticalZoom()))
705
- })
706
- },
707
- get children() {
708
- const _el$ = _tmpl$2.cloneNode(true),
709
- _el$2 = _el$.firstChild,
710
- _el$3 = _el$2.nextSibling,
711
- _el$4 = _el$3.firstChild;
712
- _el$.style.setProperty("display", "flex");
713
- _el$.style.setProperty("flex", "1");
714
- _el$.style.setProperty("height", "100%");
715
- _el$.style.setProperty("flex-direction", "row");
716
- _el$2.style.setProperty("margin-block-start", "0");
717
- _el$2.style.setProperty("padding-inline-start", "0");
718
- _el$2.style.setProperty("width", "150px");
719
- web.insert(_el$2, web.createComponent(solidJs.Index, {
720
- get each() {
721
- return allProps.tracks;
722
- },
723
- children: track => (() => {
724
- const _el$6 = _tmpl$3.cloneNode(true);
725
- _el$6.$$click = () => {
726
- if (track() === allProps.selectedTrack) {
727
- allProps.onSelectedTrackChange(undefined);
728
- } else {
729
- allProps.onSelectedTrackChange(track());
730
- }
731
- };
732
- _el$6.style.setProperty("width", "150px");
733
- _el$6.style.setProperty("height", "30px");
734
- _el$6.style.setProperty("list-style", "none");
735
- _el$6.style.setProperty("display", "flex");
736
- _el$6.style.setProperty("align-items", "center");
737
- _el$6.style.setProperty("border-top", "1px black solid");
738
- _el$6.style.setProperty("cursor", "pointer");
739
- web.insert(_el$6, () => track().name);
740
- web.effect(() => _el$6.style.setProperty("background", track() === allProps.selectedTrack ? "lightgray" : "none"));
741
- return _el$6;
742
- })()
743
- }));
744
- _el$3.style.setProperty("flex", "1");
745
- web.insert(_el$4, web.createComponent(solidJs.Show, {
746
- get when() {
747
- return !condensed();
748
- },
749
- get children() {
750
- return web.createComponent(PianoRollKeys, {});
751
- }
752
- }), null);
753
- web.insert(_el$4, web.createComponent(ScrollContainer, {
754
- ref: setScrollerRef,
755
- get children() {
756
- const _el$5 = _tmpl$$1.cloneNode(true);
757
- _el$5.style.setProperty("margin", "0");
758
- _el$5.style.setProperty("margin-block-start", "0");
759
- _el$5.style.setProperty("padding-inline-start", "0");
760
- 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, {
761
744
  get each() {
762
745
  return allProps.tracks;
763
746
  },
764
- children: track => {
765
- const notes = useNotes();
766
- solidJs.createEffect(() => {
767
- notes.onNotesChange(track().notes);
768
- });
769
- const [context, setContext] = store.createStore({
770
- ...contextProps
771
- });
772
- solidJs.createEffect(() => {
773
- setContext({
774
- ...contextProps,
775
- condensed: condensed(),
776
- notes: notes.notes(),
777
- onNoteChange: notes.onNoteChange,
778
- onInsertNote: notes.onInsertNote,
779
- onRemoveNote: notes.onRemoveNote
780
- });
781
- });
782
- const verticalViewPort = useViewPortDimension("vertical");
783
- return web.createComponent(solidJs.Show, {
784
- get when() {
785
- return condensed() || allProps.selectedTrack === track();
786
- },
787
- get children() {
788
- return web.createComponent(PianoRollContextProvider, {
789
- value: context,
790
- get children() {
791
- const _el$7 = _tmpl$3.cloneNode(true);
792
- _el$7.style.setProperty("display", "flex");
793
- _el$7.style.setProperty("position", "relative");
794
- _el$7.style.setProperty("list-style", "none");
795
- _el$7.style.setProperty("flex-direction", "row");
796
- _el$7.style.setProperty("border-top", "1px black solid");
797
- web.insert(_el$7, web.createComponent(PianoRollNotes, {}), null);
798
- web.insert(_el$7, web.createComponent(PianoRollGrid, {}), null);
799
- web.effect(() => _el$7.style.setProperty("height", condensed() ? "30px" : `${verticalViewPort.pixelSize}px`));
800
- return _el$7;
801
- }
802
- });
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);
803
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)
804
850
  });
805
851
  }
806
- }));
807
- return _el$5;
808
- }
809
- }), null);
810
- web.insert(_el$4, web.createComponent(solidJs.Show, {
811
- get when() {
812
- return !condensed();
813
- },
814
- get children() {
815
- return web.createComponent(VerticalZoomControl, {
852
+ }), null);
853
+ web.insert(_el$4, web.createComponent(HorizontalZoomControl, {
854
+ style: {
855
+ width: "100%",
856
+ "margin-left": 0
857
+ },
816
858
  get value() {
817
- return contextProps.verticalZoom;
859
+ return contextProps.zoom;
818
860
  },
819
- 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
820
872
  });
821
- }
822
- }), null);
823
- web.insert(_el$3, web.createComponent(HorizontalZoomControl, {
824
- style: {
825
- width: "100%",
826
- "margin-left": 0
827
- },
828
- get value() {
829
- return contextProps.zoom;
830
- },
831
- onInput: event => contextProps.onZoomChange?.(event.currentTarget.valueAsNumber)
832
- }), null);
833
- web.effect(_p$ => {
834
- const _v$ = styles$3.PianoRoll,
835
- _v$2 = styles$3.PianoRollContainer;
836
- _v$ !== _p$._v$ && web.className(_el$3, _p$._v$ = _v$);
837
- _v$2 !== _p$._v$2 && web.className(_el$4, _p$._v$2 = _v$2);
838
- return _p$;
839
- }, {
840
- _v$: undefined,
841
- _v$2: undefined
842
- });
843
- return _el$;
844
- }
845
- });
846
- }
847
- });
873
+ return _el$4;
874
+ })()];
875
+ }
876
+ });
877
+ }
878
+ }));
879
+ return _el$;
880
+ })();
848
881
  };
849
882
  web.delegateEvents(["click"]);
850
883
 
851
- const _tmpl$ = /*#__PURE__*/web.template(`<div><div></div></div>`, 4);
884
+ const _tmpl$$1 = /*#__PURE__*/web.template(`<div><div></div></div>`, 4);
852
885
  const PianoRoll = allProps => {
853
886
  const [contextProps, divProps] = splitContextProps(allProps);
854
887
  const [scrollerRef, setScrollerRef] = solidJs.createSignal();
@@ -861,7 +894,7 @@ const PianoRoll = allProps => {
861
894
  return web.createComponent(PianoRollContextProvider, {
862
895
  value: contextProps,
863
896
  get children() {
864
- const _el$ = _tmpl$.cloneNode(true),
897
+ const _el$ = _tmpl$$1.cloneNode(true),
865
898
  _el$2 = _el$.firstChild;
866
899
  web.spread(_el$, web.mergeProps(divProps, {
867
900
  get ["class"]() {
@@ -893,7 +926,7 @@ const PianoRoll = allProps => {
893
926
  return [web.createComponent(PianoRollKeys, {}), web.createComponent(ScrollContainer, {
894
927
  ref: setScrollerRef,
895
928
  get children() {
896
- return [web.createComponent(PianoRollGrid, {}), web.createComponent(PianoRollNotes, {})];
929
+ return [web.memo(() => allProps.children), web.createComponent(PianoRollGrid, {}), web.createComponent(PianoRollNotes, {})];
897
930
  }
898
931
  }), web.createComponent(VerticalZoomControl, {
899
932
  get min() {
@@ -919,6 +952,60 @@ const PianoRoll = allProps => {
919
952
  });
920
953
  };
921
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
+
922
1009
  const usePianoRoll = () => {
923
1010
  const [ppq, onPpqChange] = solidJs.createSignal(120);
924
1011
  const [condensed, onCondensedChange] = solidJs.createSignal(false);
@@ -926,7 +1013,7 @@ const usePianoRoll = () => {
926
1013
  const [zoom, onZoomChange] = solidJs.createSignal(10);
927
1014
  const [verticalZoom, onVerticalZoomChange] = solidJs.createSignal(5);
928
1015
  const [verticalPosition, onVerticalPositionChange] = solidJs.createSignal(64);
929
- const [gridDivision, onGridDivisionChange] = solidJs.createSignal(16);
1016
+ const [gridDivision, onGridDivisionChange] = solidJs.createSignal(4);
930
1017
  const [snapToGrid, onSnapToGridChange] = solidJs.createSignal(true);
931
1018
  const [duration, onDurationChange] = solidJs.createSignal(0);
932
1019
  return {
@@ -953,6 +1040,7 @@ const usePianoRoll = () => {
953
1040
 
954
1041
  exports.MultiTrackPianoRoll = MultiTrackPianoRoll;
955
1042
  exports.PianoRoll = PianoRoll;
1043
+ exports.PlayHead = PlayHead;
956
1044
  exports.useNotes = useNotes;
957
1045
  exports.usePianoRoll = usePianoRoll;
958
1046
  //# sourceMappingURL=index.js.map