solid-pianoroll 0.0.23 → 0.0.24

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.
@@ -25,6 +25,7 @@ const PianoRoll = (allProps) => {
25
25
  <Show when={context.showTrackList}>
26
26
  <div style={{
27
27
  height: "30px",
28
+ "border-right": "1px black solid",
28
29
  }}>
29
30
  <button title={context.mode === "keys" ? "Tracks Mode" : "Keys Mode"} onClick={() => context.onModeChange(context.mode === "keys" ? "tracks" : "keys")} style={{
30
31
  "font-size": "16px",
@@ -48,22 +49,25 @@ const PianoRoll = (allProps) => {
48
49
  </div>
49
50
  </div>
50
51
 
51
- <div style={{
52
+ <PianoRollNotesScroller>
53
+ {allProps.children}
54
+ <div style={{
52
55
  width: "100%",
53
56
  display: "flex",
54
57
  height: "100%",
55
58
  "flex-direction": "column",
56
59
  overflow: "hidden",
57
60
  }}>
58
- <div style={{ height: "30px" }}>
59
- <PianoRollScale />
61
+ <div style={{ height: "30px" }}>
62
+ <PianoRollScale />
63
+ </div>
64
+
65
+ <div style={{ flex: 1, position: "relative", overflow: "hidden" }}>
66
+ <PianoRollGrid />
67
+ <PianoRollNotes />
68
+ </div>
60
69
  </div>
61
- <PianoRollNotesScroller>
62
- {allProps.children}
63
- <PianoRollGrid />
64
- <PianoRollNotes />
65
- </PianoRollNotesScroller>
66
- </div>
70
+ </PianoRollNotesScroller>
67
71
 
68
72
  <ZoomSliderControl orientation="vertical" disabled={context.mode !== "keys"}/>
69
73
  </div>
@@ -14,9 +14,6 @@ const PianoRollNotes = (props) => {
14
14
  const [currentNoteTrackIndex, setCurrentNoteTrackIndex] = createSignal(-1);
15
15
  const [diffPosition, setDiffPosition] = createSignal(0);
16
16
  const [getInitialNote, setInitialNote] = createSignal();
17
- const snapValueToGridIfEnabled = (value, altKey) => context.snapToGrid && !altKey
18
- ? Math.round(value / gridDivisionTicks()) * gridDivisionTicks()
19
- : value;
20
17
  const calculateNoteDragValues = (event) => {
21
18
  const targetTrackIndex = context.mode === "tracks"
22
19
  ? clamp(Math.floor(verticalViewPort().calculatePosition(event.clientY)), 0, context.tracks.length - 1)
@@ -40,7 +37,7 @@ const PianoRollNotes = (props) => {
40
37
  if (!note)
41
38
  return;
42
39
  const { targetTrackIndex, midi, horiontalPosition } = calculateNoteDragValues(mouseMoveEvent);
43
- const ticks = snapValueToGridIfEnabled(horiontalPosition - diffPosition(), mouseMoveEvent.altKey);
40
+ const ticks = context.snapValueToGridIfEnabled(horiontalPosition - diffPosition(), mouseMoveEvent.altKey);
44
41
  const updatedNote = {
45
42
  ...note,
46
43
  midi,
@@ -49,13 +46,13 @@ const PianoRollNotes = (props) => {
49
46
  ticks: ticks < note.ticks + note.durationTicks ? ticks : note.ticks + note.durationTicks,
50
47
  durationTicks: ticks < note.ticks + note.durationTicks
51
48
  ? note.ticks + note.durationTicks - ticks
52
- : snapValueToGridIfEnabled(horiontalPosition - note.ticks, mouseMoveEvent.altKey),
49
+ : context.snapValueToGridIfEnabled(horiontalPosition - note.ticks, mouseMoveEvent.altKey),
53
50
  }),
54
51
  ...(noteDragMode() === "trimEnd" && {
55
52
  ticks: ticks < note.ticks ? ticks : note.ticks,
56
53
  durationTicks: ticks < note.ticks
57
54
  ? note.ticks - ticks
58
- : snapValueToGridIfEnabled(horiontalPosition - note.ticks, mouseMoveEvent.altKey),
55
+ : context.snapValueToGridIfEnabled(horiontalPosition - note.ticks, mouseMoveEvent.altKey),
59
56
  }),
60
57
  };
61
58
  const previousTrackIndex = currentNoteTrackIndex();
@@ -90,7 +87,7 @@ const PianoRollNotes = (props) => {
90
87
  mouseDownEvent.preventDefault();
91
88
  mouseDownEvent.stopPropagation();
92
89
  const { targetTrackIndex, midi, horiontalPosition } = calculateNoteDragValues(mouseDownEvent);
93
- const ticks = snapValueToGridIfEnabled(horiontalPosition, mouseDownEvent.altKey);
90
+ const ticks = context.snapValueToGridIfEnabled(horiontalPosition, mouseDownEvent.altKey, context);
94
91
  const durationTicks = gridDivisionTicks();
95
92
  const newNote = {
96
93
  midi,
@@ -145,7 +142,8 @@ const PianoRollNotes = (props) => {
145
142
  setInitialNote(note);
146
143
  startDragging();
147
144
  }} style={{
148
- "background-color": `rgba(255,0,0, ${(128 + note.velocity) / 256})`,
145
+ "background-color": `${track.color}`,
146
+ opacity: (note.velocity / 128 + 2) / 3,
149
147
  top: `${verticalVirtualDimensions().offset}px`,
150
148
  height: `${verticalVirtualDimensions().size}px`,
151
149
  left: `${horizontalDimensions().offset}px`,
@@ -2,10 +2,24 @@ import { createMemo, Index, Show } from "solid-js";
2
2
  import { useViewPortDimension } from "./viewport/ScrollZoomViewPort";
3
3
  import styles from "./PianoRollScale.module.css";
4
4
  import usePianoRollGrid from "./usePianoRollGrid";
5
+ import { usePianoRollContext } from "./PianoRollContext";
5
6
  const PianoRollScale = () => {
6
7
  const horizontalViewPort = createMemo(() => useViewPortDimension("horizontal"));
7
8
  const grid = usePianoRollGrid();
8
- return (<div class={styles.PianoRollScale}>
9
+ const context = usePianoRollContext();
10
+ const updatePlayheadPosition = (event) => {
11
+ const position = horizontalViewPort().calculatePosition(event.clientX);
12
+ context.onPlayHeadPositionChange(position, event);
13
+ };
14
+ return (<div class={styles.PianoRollScale} onMouseDown={(event) => {
15
+ updatePlayheadPosition(event);
16
+ const handleMouseUp = () => {
17
+ window.removeEventListener("mousemove", updatePlayheadPosition);
18
+ window.removeEventListener("mouseup", handleMouseUp);
19
+ };
20
+ window.addEventListener("mousemove", updatePlayheadPosition);
21
+ window.addEventListener("mouseup", handleMouseUp);
22
+ }}>
9
23
  <Index each={grid()}>
10
24
  {(entry) => {
11
25
  return (<Show when={horizontalViewPort().isVisible(entry().virtualDimensions)}>
@@ -9,6 +9,7 @@ const defaultState = {
9
9
  verticalPosition: 44,
10
10
  verticalTrackZoom: 0.5,
11
11
  verticalTrackPosition: 0,
12
+ playHeadPosition: 0,
12
13
  gridDivision: 4,
13
14
  snapToGrid: true,
14
15
  duration: 0,
@@ -28,6 +29,7 @@ export const pianoRollStatePropNames = [
28
29
  "onNoteDown",
29
30
  "onNoteUp",
30
31
  "isKeyDown",
32
+ "snapValueToGridIfEnabled",
31
33
  ];
32
34
  const createPianoRollstate = (initialState) => {
33
35
  const [state, setState] = createStore({
@@ -35,11 +37,21 @@ const createPianoRollstate = (initialState) => {
35
37
  ...initialState,
36
38
  });
37
39
  const handlers = Object.fromEntries(Object.entries(state).map((entry) => {
40
+ const handlerName = propNameToHandlerName(entry[0]);
38
41
  return [
39
- propNameToHandlerName(entry[0]),
40
- (value) => setState(entry[0], value),
42
+ handlerName,
43
+ (value, originalEvent) => {
44
+ const handler = initialState?.[handlerName];
45
+ setState(entry[0], value);
46
+ if (handler) {
47
+ handler(value, originalEvent);
48
+ }
49
+ },
41
50
  ];
42
51
  }));
52
+ const onPlayheadPositionChange = (playheadPosition, originalEvent) => {
53
+ handlers.onPlayHeadPositionChange(snapValueToGridIfEnabled(playheadPosition, !!originalEvent?.altKey));
54
+ };
43
55
  const updateNotes = async (trackIndex, getNotes) => {
44
56
  const track = state.tracks[trackIndex];
45
57
  if (!track)
@@ -93,6 +105,12 @@ const createPianoRollstate = (initialState) => {
93
105
  updateKeyPressedState(trackIndex, keyNumber, false);
94
106
  };
95
107
  const isKeyDown = (trackIndex, keyNumber) => !!state.pressedKeys[trackIndex]?.[keyNumber];
108
+ const snapValueToGridIfEnabled = (value, altKey) => {
109
+ const gridDivisionTicks = (state.ppq * 4) / state.gridDivision;
110
+ return state.snapToGrid && !altKey
111
+ ? Math.round(value / gridDivisionTicks) * gridDivisionTicks
112
+ : value;
113
+ };
96
114
  return mergeProps(state, {
97
115
  ...handlers,
98
116
  onNoteChange,
@@ -101,6 +119,8 @@ const createPianoRollstate = (initialState) => {
101
119
  onNoteDown,
102
120
  onNoteUp,
103
121
  isKeyDown,
122
+ snapValueToGridIfEnabled,
123
+ onPlayheadPositionChange,
104
124
  });
105
125
  };
106
126
  export default createPianoRollstate;
@@ -28,9 +28,9 @@ const PlayHead = (allProps) => {
28
28
  }} onMouseDown={(event) => {
29
29
  event.preventDefault();
30
30
  event.stopPropagation();
31
- const handleMouseMove = ({ clientX }) => {
32
- const newPosition = viewPort.calculatePosition(clientX);
33
- props.onPositionChange?.(newPosition);
31
+ const handleMouseMove = (event) => {
32
+ const newPosition = viewPort.calculatePosition(event.clientX);
33
+ props.onPositionChange?.(newPosition, event);
34
34
  };
35
35
  const handleMouseUp = () => {
36
36
  window.removeEventListener("mousemove", handleMouseMove);
@@ -1,6 +1,5 @@
1
1
  import { JSX, ParentProps } from "solid-js";
2
2
  import createPianoRollstate from "./usePianoRollState";
3
- export type GridDivision = 1 | 2 | 4 | 8 | 16 | 32 | 64;
4
3
  export type PianoRollProps = {
5
4
  showAllTracks?: boolean;
6
5
  showTrackList?: boolean;
@@ -1,90 +1,11 @@
1
1
  import { PianoRollProps } from "./PianoRoll";
2
- export declare const PianoRollContextProvider: import("solid-js/types/reactive/signal").ContextProviderComponent<{
2
+ import createPianoRollstate from "./usePianoRollState";
3
+ export type PianoRollContext = {
3
4
  showAllTracks?: boolean;
4
5
  showTrackList?: boolean;
5
- } & {
6
- ppq: number;
7
- mode: "keys" | "tracks";
8
- position: number;
9
- zoom: number;
10
- verticalZoom: number;
11
- verticalPosition: number;
12
- verticalTrackZoom: number;
13
- verticalTrackPosition: number;
14
- gridDivision: import("./PianoRoll").GridDivision;
15
- snapToGrid: boolean;
16
- duration: number;
17
- tracks: import("./types").Track[];
18
- selectedTrackIndex: number;
19
- pressedKeys: Record<number, Record<number, boolean>>;
20
- notesScrollerClientRect: Pick<import("./useBoundingClientRect").ClientRect, "height" | "width" | "left" | "top">;
21
- tracksScrollerClientRect: Pick<import("./useBoundingClientRect").ClientRect, "height" | "width" | "left" | "top">;
22
- onNoteChange: (trackIndex: number, noteIndex: number, note: import("./types").Note) => void;
23
- onInsertNote: (trackIndex: number, note: import("./types").Note) => number;
24
- onRemoveNote: (trackIndex: number, noteIndex: number) => void;
25
- onNoteDown: (trackIndex: number, keyNumber: number) => void;
26
- onNoteUp: (trackIndex: number, keyNumber: number) => void;
27
- isKeyDown: (trackIndex: number, keyNumber: number) => boolean;
28
- onPpqChange: (value: number) => void;
29
- onModeChange: (value: "keys" | "tracks") => void;
30
- onPositionChange: (value: number) => void;
31
- onZoomChange: (value: number) => void;
32
- onVerticalZoomChange: (value: number) => void;
33
- onVerticalPositionChange: (value: number) => void;
34
- onVerticalTrackZoomChange: (value: number) => void;
35
- onVerticalTrackPositionChange: (value: number) => void;
36
- onGridDivisionChange: (value: import("./PianoRoll").GridDivision) => void;
37
- onSnapToGridChange: (value: boolean) => void;
38
- onDurationChange: (value: number) => void;
39
- onTracksChange: (value: import("./types").Track[]) => void;
40
- onSelectedTrackIndexChange: (value: number) => void;
41
- onPressedKeysChange: (value: Record<number, Record<number, boolean>>) => void;
42
- onNotesScrollerClientRectChange: (value: Pick<import("./useBoundingClientRect").ClientRect, "height" | "width" | "left" | "top">) => void;
43
- onTracksScrollerClientRectChange: (value: Pick<import("./useBoundingClientRect").ClientRect, "height" | "width" | "left" | "top">) => void;
44
- }>;
45
- export declare const usePianoRollContext: () => {
46
- showAllTracks?: boolean;
47
- showTrackList?: boolean;
48
- } & {
49
- ppq: number;
50
- mode: "keys" | "tracks";
51
- position: number;
52
- zoom: number;
53
- verticalZoom: number;
54
- verticalPosition: number;
55
- verticalTrackZoom: number;
56
- verticalTrackPosition: number;
57
- gridDivision: import("./PianoRoll").GridDivision;
58
- snapToGrid: boolean;
59
- duration: number;
60
- tracks: import("./types").Track[];
61
- selectedTrackIndex: number;
62
- pressedKeys: Record<number, Record<number, boolean>>;
63
- notesScrollerClientRect: Pick<import("./useBoundingClientRect").ClientRect, "height" | "width" | "left" | "top">;
64
- tracksScrollerClientRect: Pick<import("./useBoundingClientRect").ClientRect, "height" | "width" | "left" | "top">;
65
- onNoteChange: (trackIndex: number, noteIndex: number, note: import("./types").Note) => void;
66
- onInsertNote: (trackIndex: number, note: import("./types").Note) => number;
67
- onRemoveNote: (trackIndex: number, noteIndex: number) => void;
68
- onNoteDown: (trackIndex: number, keyNumber: number) => void;
69
- onNoteUp: (trackIndex: number, keyNumber: number) => void;
70
- isKeyDown: (trackIndex: number, keyNumber: number) => boolean;
71
- onPpqChange: (value: number) => void;
72
- onModeChange: (value: "keys" | "tracks") => void;
73
- onPositionChange: (value: number) => void;
74
- onZoomChange: (value: number) => void;
75
- onVerticalZoomChange: (value: number) => void;
76
- onVerticalPositionChange: (value: number) => void;
77
- onVerticalTrackZoomChange: (value: number) => void;
78
- onVerticalTrackPositionChange: (value: number) => void;
79
- onGridDivisionChange: (value: import("./PianoRoll").GridDivision) => void;
80
- onSnapToGridChange: (value: boolean) => void;
81
- onDurationChange: (value: number) => void;
82
- onTracksChange: (value: import("./types").Track[]) => void;
83
- onSelectedTrackIndexChange: (value: number) => void;
84
- onPressedKeysChange: (value: Record<number, Record<number, boolean>>) => void;
85
- onNotesScrollerClientRectChange: (value: Pick<import("./useBoundingClientRect").ClientRect, "height" | "width" | "left" | "top">) => void;
86
- onTracksScrollerClientRectChange: (value: Pick<import("./useBoundingClientRect").ClientRect, "height" | "width" | "left" | "top">) => void;
87
- };
6
+ } & ReturnType<typeof createPianoRollstate>;
7
+ export declare const PianoRollContextProvider: import("solid-js/types/reactive/signal").ContextProviderComponent<PianoRollContext>;
8
+ export declare const usePianoRollContext: () => PianoRollContext;
88
9
  export declare const splitContextProps: (allProps: PianoRollProps) => [Pick<PianoRollProps, "onDurationChange" | keyof {
89
10
  ppq: number;
90
11
  mode: "keys" | "tracks";
@@ -94,7 +15,8 @@ export declare const splitContextProps: (allProps: PianoRollProps) => [Pick<Pian
94
15
  verticalPosition: number;
95
16
  verticalTrackZoom: number;
96
17
  verticalTrackPosition: number;
97
- gridDivision: import("./PianoRoll").GridDivision;
18
+ playHeadPosition: number;
19
+ gridDivision: import("./types").GridDivision;
98
20
  snapToGrid: boolean;
99
21
  duration: number;
100
22
  tracks: import("./types").Track[];
@@ -102,7 +24,7 @@ export declare const splitContextProps: (allProps: PianoRollProps) => [Pick<Pian
102
24
  pressedKeys: Record<number, Record<number, boolean>>;
103
25
  notesScrollerClientRect: Pick<import("./useBoundingClientRect").ClientRect, "height" | "width" | "left" | "top">;
104
26
  tracksScrollerClientRect: Pick<import("./useBoundingClientRect").ClientRect, "height" | "width" | "left" | "top">;
105
- } | "onPpqChange" | "onModeChange" | "onPositionChange" | "onZoomChange" | "onVerticalZoomChange" | "onVerticalPositionChange" | "onVerticalTrackZoomChange" | "onVerticalTrackPositionChange" | "onGridDivisionChange" | "onSnapToGridChange" | "onTracksChange" | "onSelectedTrackIndexChange" | "onPressedKeysChange" | "onNotesScrollerClientRectChange" | "onTracksScrollerClientRectChange" | "onNoteChange" | "onInsertNote" | "onRemoveNote" | "onNoteDown" | "onNoteUp" | "isKeyDown" | "showAllTracks" | "showTrackList">, Omit<PianoRollProps, "onDurationChange" | keyof {
27
+ } | "onPpqChange" | "onModeChange" | "onPositionChange" | "onZoomChange" | "onVerticalZoomChange" | "onVerticalPositionChange" | "onVerticalTrackZoomChange" | "onVerticalTrackPositionChange" | "onPlayHeadPositionChange" | "onGridDivisionChange" | "onSnapToGridChange" | "onTracksChange" | "onSelectedTrackIndexChange" | "onPressedKeysChange" | "onNotesScrollerClientRectChange" | "onTracksScrollerClientRectChange" | "onNoteChange" | "onInsertNote" | "onRemoveNote" | "onNoteDown" | "onNoteUp" | "isKeyDown" | "snapValueToGridIfEnabled" | "onPlayheadPositionChange" | "showAllTracks" | "showTrackList">, Omit<PianoRollProps, "onDurationChange" | keyof {
106
28
  ppq: number;
107
29
  mode: "keys" | "tracks";
108
30
  position: number;
@@ -111,7 +33,8 @@ export declare const splitContextProps: (allProps: PianoRollProps) => [Pick<Pian
111
33
  verticalPosition: number;
112
34
  verticalTrackZoom: number;
113
35
  verticalTrackPosition: number;
114
- gridDivision: import("./PianoRoll").GridDivision;
36
+ playHeadPosition: number;
37
+ gridDivision: import("./types").GridDivision;
115
38
  snapToGrid: boolean;
116
39
  duration: number;
117
40
  tracks: import("./types").Track[];
@@ -119,4 +42,4 @@ export declare const splitContextProps: (allProps: PianoRollProps) => [Pick<Pian
119
42
  pressedKeys: Record<number, Record<number, boolean>>;
120
43
  notesScrollerClientRect: Pick<import("./useBoundingClientRect").ClientRect, "height" | "width" | "left" | "top">;
121
44
  tracksScrollerClientRect: Pick<import("./useBoundingClientRect").ClientRect, "height" | "width" | "left" | "top">;
122
- } | "onPpqChange" | "onModeChange" | "onPositionChange" | "onZoomChange" | "onVerticalZoomChange" | "onVerticalPositionChange" | "onVerticalTrackZoomChange" | "onVerticalTrackPositionChange" | "onGridDivisionChange" | "onSnapToGridChange" | "onTracksChange" | "onSelectedTrackIndexChange" | "onPressedKeysChange" | "onNotesScrollerClientRectChange" | "onTracksScrollerClientRectChange" | "onNoteChange" | "onInsertNote" | "onRemoveNote" | "onNoteDown" | "onNoteUp" | "isKeyDown" | "showAllTracks" | "showTrackList">];
45
+ } | "onPpqChange" | "onModeChange" | "onPositionChange" | "onZoomChange" | "onVerticalZoomChange" | "onVerticalPositionChange" | "onVerticalTrackZoomChange" | "onVerticalTrackPositionChange" | "onPlayHeadPositionChange" | "onGridDivisionChange" | "onSnapToGridChange" | "onTracksChange" | "onSelectedTrackIndexChange" | "onPressedKeysChange" | "onNotesScrollerClientRectChange" | "onTracksScrollerClientRectChange" | "onNoteChange" | "onInsertNote" | "onRemoveNote" | "onNoteDown" | "onNoteUp" | "isKeyDown" | "snapValueToGridIfEnabled" | "onPlayheadPositionChange" | "showAllTracks" | "showTrackList">];
@@ -2,4 +2,5 @@ import PianoRoll from "./PianoRoll";
2
2
  import PlayHead from "./viewport/PlayHead";
3
3
  import useNotes from "./useNotes";
4
4
  import createPianoRollstate from "./usePianoRollState";
5
+ export type { Note, Track, GridDivision } from "./types";
5
6
  export { PianoRoll, createPianoRollstate, useNotes, PlayHead };
@@ -1,6 +1,8 @@
1
1
  import { Midi } from "@tonejs/midi";
2
+ export type GridDivision = 1 | 2 | 4 | 8 | 16 | 32 | 64;
2
3
  export type Note = Pick<ReturnType<Midi["tracks"][number]["notes"][number]["toJSON"]>, "durationTicks" | "midi" | "ticks" | "velocity">;
3
4
  export type Track = {
4
5
  name: string;
5
6
  notes: Note[];
7
+ color: string;
6
8
  };
@@ -1,4 +1,4 @@
1
- import { GridDivision } from "./PianoRoll";
1
+ import { GridDivision } from "./types";
2
2
  import { Note, Track } from "./types";
3
3
  import { ClientRect } from "./useBoundingClientRect";
4
4
  type PianoRollState = {
@@ -10,6 +10,7 @@ type PianoRollState = {
10
10
  verticalPosition: number;
11
11
  verticalTrackZoom: number;
12
12
  verticalTrackPosition: number;
13
+ playHeadPosition: number;
13
14
  gridDivision: GridDivision;
14
15
  snapToGrid: boolean;
15
16
  duration: number;
@@ -19,8 +20,13 @@ type PianoRollState = {
19
20
  notesScrollerClientRect: Pick<ClientRect, "left" | "width" | "top" | "height">;
20
21
  tracksScrollerClientRect: Pick<ClientRect, "left" | "width" | "top" | "height">;
21
22
  };
22
- export declare const pianoRollStatePropNames: ("onDurationChange" | keyof PianoRollState | "onPpqChange" | "onModeChange" | "onPositionChange" | "onZoomChange" | "onVerticalZoomChange" | "onVerticalPositionChange" | "onVerticalTrackZoomChange" | "onVerticalTrackPositionChange" | "onGridDivisionChange" | "onSnapToGridChange" | "onTracksChange" | "onSelectedTrackIndexChange" | "onPressedKeysChange" | "onNotesScrollerClientRectChange" | "onTracksScrollerClientRectChange" | "onNoteChange" | "onInsertNote" | "onRemoveNote" | "onNoteDown" | "onNoteUp" | "isKeyDown")[];
23
- declare const createPianoRollstate: (initialState?: Partial<PianoRollState>) => {
23
+ declare const defaultState: PianoRollState;
24
+ type PropNameToHandlerName<PropName extends string> = `on${Capitalize<PropName>}Change`;
25
+ type StateChangeHandlerObject = {
26
+ [PropName in keyof typeof defaultState as PropNameToHandlerName<PropName>]: (value: typeof defaultState[PropName], originalEvent?: MouseEvent | KeyboardEvent) => void;
27
+ };
28
+ export declare const pianoRollStatePropNames: ("onDurationChange" | keyof PianoRollState | "onPpqChange" | "onModeChange" | "onPositionChange" | "onZoomChange" | "onVerticalZoomChange" | "onVerticalPositionChange" | "onVerticalTrackZoomChange" | "onVerticalTrackPositionChange" | "onPlayHeadPositionChange" | "onGridDivisionChange" | "onSnapToGridChange" | "onTracksChange" | "onSelectedTrackIndexChange" | "onPressedKeysChange" | "onNotesScrollerClientRectChange" | "onTracksScrollerClientRectChange" | "onNoteChange" | "onInsertNote" | "onRemoveNote" | "onNoteDown" | "onNoteUp" | "isKeyDown" | "snapValueToGridIfEnabled" | "onPlayheadPositionChange")[];
29
+ declare const createPianoRollstate: (initialState?: Partial<PianoRollState & StateChangeHandlerObject>) => {
24
30
  ppq: number;
25
31
  mode: "keys" | "tracks";
26
32
  position: number;
@@ -29,6 +35,7 @@ declare const createPianoRollstate: (initialState?: Partial<PianoRollState>) =>
29
35
  verticalPosition: number;
30
36
  verticalTrackZoom: number;
31
37
  verticalTrackPosition: number;
38
+ playHeadPosition: number;
32
39
  gridDivision: GridDivision;
33
40
  snapToGrid: boolean;
34
41
  duration: number;
@@ -43,21 +50,24 @@ declare const createPianoRollstate: (initialState?: Partial<PianoRollState>) =>
43
50
  onNoteDown: (trackIndex: number, keyNumber: number) => void;
44
51
  onNoteUp: (trackIndex: number, keyNumber: number) => void;
45
52
  isKeyDown: (trackIndex: number, keyNumber: number) => boolean;
46
- onPpqChange: (value: number) => void;
47
- onModeChange: (value: "keys" | "tracks") => void;
48
- onPositionChange: (value: number) => void;
49
- onZoomChange: (value: number) => void;
50
- onVerticalZoomChange: (value: number) => void;
51
- onVerticalPositionChange: (value: number) => void;
52
- onVerticalTrackZoomChange: (value: number) => void;
53
- onVerticalTrackPositionChange: (value: number) => void;
54
- onGridDivisionChange: (value: GridDivision) => void;
55
- onSnapToGridChange: (value: boolean) => void;
56
- onDurationChange: (value: number) => void;
57
- onTracksChange: (value: Track[]) => void;
58
- onSelectedTrackIndexChange: (value: number) => void;
59
- onPressedKeysChange: (value: Record<number, Record<number, boolean>>) => void;
60
- onNotesScrollerClientRectChange: (value: Pick<ClientRect, "height" | "width" | "left" | "top">) => void;
61
- onTracksScrollerClientRectChange: (value: Pick<ClientRect, "height" | "width" | "left" | "top">) => void;
53
+ snapValueToGridIfEnabled: (value: number, altKey: boolean) => number;
54
+ onPlayheadPositionChange: (playheadPosition: number, originalEvent?: MouseEvent | KeyboardEvent) => void;
55
+ onPpqChange: (value: number, originalEvent?: MouseEvent | KeyboardEvent) => void;
56
+ onModeChange: (value: "keys" | "tracks", originalEvent?: MouseEvent | KeyboardEvent) => void;
57
+ onPositionChange: (value: number, originalEvent?: MouseEvent | KeyboardEvent) => void;
58
+ onZoomChange: (value: number, originalEvent?: MouseEvent | KeyboardEvent) => void;
59
+ onVerticalZoomChange: (value: number, originalEvent?: MouseEvent | KeyboardEvent) => void;
60
+ onVerticalPositionChange: (value: number, originalEvent?: MouseEvent | KeyboardEvent) => void;
61
+ onVerticalTrackZoomChange: (value: number, originalEvent?: MouseEvent | KeyboardEvent) => void;
62
+ onVerticalTrackPositionChange: (value: number, originalEvent?: MouseEvent | KeyboardEvent) => void;
63
+ onPlayHeadPositionChange: (value: number, originalEvent?: MouseEvent | KeyboardEvent) => void;
64
+ onGridDivisionChange: (value: GridDivision, originalEvent?: MouseEvent | KeyboardEvent) => void;
65
+ onSnapToGridChange: (value: boolean, originalEvent?: MouseEvent | KeyboardEvent) => void;
66
+ onDurationChange: (value: number, originalEvent?: MouseEvent | KeyboardEvent) => void;
67
+ onTracksChange: (value: Track[], originalEvent?: MouseEvent | KeyboardEvent) => void;
68
+ onSelectedTrackIndexChange: (value: number, originalEvent?: MouseEvent | KeyboardEvent) => void;
69
+ onPressedKeysChange: (value: Record<number, Record<number, boolean>>, originalEvent?: MouseEvent | KeyboardEvent) => void;
70
+ onNotesScrollerClientRectChange: (value: Pick<ClientRect, "height" | "width" | "left" | "top">, originalEvent?: MouseEvent | KeyboardEvent) => void;
71
+ onTracksScrollerClientRectChange: (value: Pick<ClientRect, "height" | "width" | "left" | "top">, originalEvent?: MouseEvent | KeyboardEvent) => void;
62
72
  };
63
73
  export default createPianoRollstate;
@@ -1,7 +1,7 @@
1
1
  import { JSX } from "solid-js";
2
2
  declare const PlayHead: (allProps: {
3
3
  position: number;
4
- onPositionChange?: (playHeadPosition: number) => void;
4
+ onPositionChange?: (playHeadPosition: number, event: MouseEvent) => void;
5
5
  sync?: boolean;
6
6
  dimensionName?: string;
7
7
  } & JSX.HTMLAttributes<HTMLDivElement>) => JSX.Element;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.0.23",
2
+ "version": "0.0.24",
3
3
  "name": "solid-pianoroll",
4
4
  "description": "Pianoroll UI Control for Solid JS apps",
5
5
  "license": "MIT",