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.
- package/dist/cjs/index.js +82 -40
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +82 -40
- package/dist/esm/index.js.map +1 -1
- package/dist/source/PianoRoll.jsx +13 -9
- package/dist/source/PianoRollNotes.jsx +6 -8
- package/dist/source/PianoRollScale.jsx +15 -1
- package/dist/source/usePianoRollState.js +22 -2
- package/dist/source/viewport/PlayHead.jsx +3 -3
- package/dist/types/PianoRoll.d.ts +0 -1
- package/dist/types/PianoRollContext.d.ts +11 -88
- package/dist/types/index.d.ts +1 -0
- package/dist/types/types.d.ts +2 -0
- package/dist/types/usePianoRollState.d.ts +29 -19
- package/dist/types/viewport/PlayHead.d.ts +1 -1
- package/package.json +1 -1
|
@@ -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
|
-
<
|
|
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
|
-
|
|
59
|
-
|
|
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
|
-
|
|
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":
|
|
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
|
-
|
|
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
|
-
|
|
40
|
-
(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 = (
|
|
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,90 +1,11 @@
|
|
|
1
1
|
import { PianoRollProps } from "./PianoRoll";
|
|
2
|
-
|
|
2
|
+
import createPianoRollstate from "./usePianoRollState";
|
|
3
|
+
export type PianoRollContext = {
|
|
3
4
|
showAllTracks?: boolean;
|
|
4
5
|
showTrackList?: boolean;
|
|
5
|
-
} &
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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">];
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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 };
|
package/dist/types/types.d.ts
CHANGED
|
@@ -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 "./
|
|
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
|
-
|
|
23
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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