solid-pianoroll 0.0.21 → 0.0.22

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/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { createComponent, use, spread, mergeProps as mergeProps$1, insert, effect, template, delegateEvents, className, classList, setAttribute, memo } from 'solid-js/web';
2
- import { mergeProps, createContext, splitProps, useContext, createEffect, createMemo, createSignal, Index, Show, batch, For } from 'solid-js';
1
+ import { createComponent, use, spread, mergeProps as mergeProps$1, insert, effect, template, delegateEvents, classList, setAttribute, className, memo } from 'solid-js/web';
2
+ import { mergeProps, createContext, splitProps, useContext, createEffect, createMemo, createSignal, Index, Show, For } from 'solid-js';
3
3
  import { createStore } from 'solid-js/store';
4
4
 
5
5
  function styleInject(css, ref) {
@@ -27,8 +27,8 @@ function styleInject(css, ref) {
27
27
  }
28
28
  }
29
29
 
30
- var css_248z$5 = ".PianoRoll-module_PianoRoll__rkRYx {\n box-sizing: border-box;\n display: flex;\n overflow: hidden;\n flex-direction: column;\n height: 100%;\n}\n\n.PianoRoll-module_PianoRollContainer__Oyxr7 {\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: row;\n}\n";
31
- var styles$5 = {"PianoRoll":"PianoRoll-module_PianoRoll__rkRYx","PianoRollContainer":"PianoRoll-module_PianoRollContainer__Oyxr7"};
30
+ var css_248z$5 = ".PianoRoll-module_PianoRoll__rkRYx {\n box-sizing: border-box;\n display: flex;\n overflow: hidden;\n flex-direction: column;\n height: 100%;\n}\n\n.PianoRoll-module_PianoRollContainer__Oyxr7 {\n overflow: hidden;\n height: 100%;\n display: flex;\n flex-direction: row;\n}\n\n.PianoRoll-module_PianoRollLeftColumn__S6SZQ {\n display: flex;\n width: 30%;\n max-width: 250px;\n}\n";
31
+ var styles$5 = {"PianoRoll":"PianoRoll-module_PianoRoll__rkRYx","PianoRollContainer":"PianoRoll-module_PianoRollContainer__Oyxr7","PianoRollLeftColumn":"PianoRoll-module_PianoRollLeftColumn__S6SZQ"};
32
32
  styleInject(css_248z$5);
33
33
 
34
34
  const defaultState = {
@@ -45,10 +45,10 @@ const defaultState = {
45
45
  duration: 0,
46
46
  tracks: [],
47
47
  selectedTrackIndex: 0,
48
- pressedKeys: []
48
+ pressedKeys: {}
49
49
  };
50
50
  const propNameToHandlerName = name => `on${name[0]?.toUpperCase()}${name.slice(1)}Change`;
51
- const pianoRollStatePropNames = [...Object.keys(defaultState), ...Object.keys(defaultState).map(propNameToHandlerName), "onNoteChange", "onInsertNote", "onRemoveNote", "onNoteDown", "onNoteUp"];
51
+ const pianoRollStatePropNames = [...Object.keys(defaultState), ...Object.keys(defaultState).map(propNameToHandlerName), "onNoteChange", "onInsertNote", "onRemoveNote", "onNoteDown", "onNoteUp", "isKeyDown"];
52
52
  const createPianoRollstate = initialState => {
53
53
  const [state, setState] = createStore({
54
54
  ...defaultState,
@@ -82,19 +82,30 @@ const createPianoRollstate = initialState => {
82
82
  const onRemoveNote = (trackIndex, noteIndex) => {
83
83
  updateNotes(trackIndex, notes => [...notes.slice(0, noteIndex), ...notes.slice(noteIndex + 1)]);
84
84
  };
85
- const onNoteDown = keyNumber => {
86
- handlers.onPressedKeysChange?.([...state.pressedKeys, keyNumber]);
85
+ const updateKeyPressedState = (trackIndex, keyNumber, value) => {
86
+ handlers.onPressedKeysChange?.({
87
+ ...state.pressedKeys,
88
+ [trackIndex]: {
89
+ ...state.pressedKeys[trackIndex],
90
+ [keyNumber]: value
91
+ }
92
+ });
87
93
  };
88
- const onNoteUp = keyNumber => {
89
- handlers.onPressedKeysChange?.([...state.pressedKeys].filter(number => number !== keyNumber));
94
+ const onNoteDown = (trackIndex, keyNumber) => {
95
+ updateKeyPressedState(trackIndex, keyNumber, true);
90
96
  };
97
+ const onNoteUp = (trackIndex, keyNumber) => {
98
+ updateKeyPressedState(trackIndex, keyNumber, false);
99
+ };
100
+ const isKeyDown = (trackIndex, keyNumber) => !!state.pressedKeys[trackIndex]?.[keyNumber];
91
101
  return mergeProps(state, {
92
102
  ...handlers,
93
103
  onNoteChange,
94
104
  onInsertNote,
95
105
  onRemoveNote,
96
106
  onNoteDown,
97
- onNoteUp
107
+ onNoteUp,
108
+ isKeyDown
98
109
  });
99
110
  };
100
111
 
@@ -107,7 +118,7 @@ const usePianoRollContext = () => {
107
118
  };
108
119
  const splitContextProps = allProps => splitProps(allProps, [...pianoRollStatePropNames, "showAllTracks", "showTrackList"]);
109
120
 
110
- var css_248z$4 = ".PianoRollKeys-module_PianoRollKeys__5vnQ0 {\n position: relative;\n height: 100%;\n border-width: 0;\n border-color: #000;\n border-style: solid;\n border-right-width: 1px;\n border-left-width: 1px;\n background: white;\n cursor: pointer;\n}\n\n.PianoRollKeys-module_Key__jybNC {\n transition-property: background-color, box-shadow;\n transition-duration: 200ms;\n transition-timing-function: ease-out;\n border-width: 0px;\n position: absolute;\n box-sizing: border-box;\n width: 120%;\n left: -20%;\n border-color: #000;\n border-style: solid;\n}\n\n.PianoRollKeys-module_black__7rncB {\n background: black;\n border-top-right-radius: 12%;\n border-bottom-right-radius: 12%;\n margin-left: -20%;\n z-index: 1;\n}\n\n.PianoRollKeys-module_white__fR2Lm {\n background: white;\n border-top-width: 0.5px;\n border-bottom-width: 0.5px;\n}\n\n.PianoRollKeys-module_down__GcNeZ {\n transition: none;\n background: red;\n}\n";
121
+ var css_248z$4 = ".PianoRollKeys-module_PianoRollKeys__5vnQ0 {\n position: relative;\n height: 100%;\n border-width: 0;\n border-color: #000;\n border-style: solid;\n border-right-width: 1px;\n border-left-width: 1px;\n background: white;\n cursor: pointer;\n}\n\n.PianoRollKeys-module_Key__jybNC {\n transition-property: background-color, box-shadow;\n transition-duration: 200ms;\n transition-timing-function: ease-out;\n border-width: 0px;\n position: absolute;\n box-sizing: border-box;\n width: 120%;\n left: -20%;\n border-color: #000;\n border-style: solid;\n transform: rotateX(0deg);\n perspective: 100px;\n}\n\n.PianoRollKeys-module_black__7rncB {\n background: black;\n border-top-right-radius: 12%;\n border-bottom-right-radius: 12%;\n margin-left: -20%;\n z-index: 1;\n border: 1px black outset;\n}\n\n.PianoRollKeys-module_white__fR2Lm {\n background: white;\n border-top-width: 0.5px;\n border-bottom-width: 0.5px;\n border-top-right-radius: 4%;\n border-bottom-right-radius: 4%;\n}\n\n.PianoRollKeys-module_down__GcNeZ {\n transition: none;\n background: red;\n transform: rotateX(0deg) rotateY(20deg);\n}\n";
111
122
  var styles$4 = {"PianoRollKeys":"PianoRollKeys-module_PianoRollKeys__5vnQ0","Key":"PianoRollKeys-module_Key__jybNC","black":"PianoRollKeys-module_black__7rncB","white":"PianoRollKeys-module_white__fR2Lm","down":"PianoRollKeys-module_down__GcNeZ"};
112
123
  styleInject(css_248z$4);
113
124
 
@@ -350,7 +361,7 @@ const PianoRollKeys = () => {
350
361
  return createComponent(Index, {
351
362
  each: keys,
352
363
  children: key => {
353
- const isDown = createMemo(() => context.pressedKeys.includes(key().number));
364
+ const isDown = createMemo(() => context.isKeyDown(context.selectedTrackIndex, key().number));
354
365
  const virtualDimensions = createMemo(() => verticalViewPort().calculatePixelDimensions(127 - key().number, 1));
355
366
  const previousIsBlack = blackKeys.includes((key().number - 1) % 12);
356
367
  const nextIsBlack = blackKeys.includes((key().number + 1) % 12);
@@ -362,69 +373,47 @@ const PianoRollKeys = () => {
362
373
  const _el$2 = _tmpl$$6.cloneNode(true);
363
374
  _el$2.addEventListener("mouseleave", () => {
364
375
  if (isMouseDown()) {
365
- context.onNoteUp(key().number);
376
+ context.onNoteUp(context.selectedTrackIndex, key().number);
366
377
  }
367
378
  });
368
379
  _el$2.addEventListener("mouseenter", () => {
369
380
  if (isMouseDown()) {
370
- context.onNoteDown(key().number);
381
+ context.onNoteDown(context.selectedTrackIndex, key().number);
371
382
  }
372
383
  });
373
384
  _el$2.$$mouseup = () => {
374
- context.onNoteUp(key().number);
385
+ context.onNoteUp(context.selectedTrackIndex, key().number);
375
386
  };
376
387
  _el$2.$$mousedown = () => {
377
388
  setIsMouseDown(true);
378
- context.onNoteDown(key().number);
389
+ context.onNoteDown(context.selectedTrackIndex, key().number);
379
390
  };
380
- insert(_el$2, createComponent(Show, {
381
- get when() {
382
- return key().isBlack && false;
383
- },
384
- get children() {
385
- const _el$3 = _tmpl$$6.cloneNode(true);
386
- effect(_p$ => {
387
- const _v$3 = styles$4["black-separator"],
388
- _v$4 = `${virtualDimensions().offset}px`,
389
- _v$5 = `${virtualDimensions().size / 2 - 0.25}px`;
390
- _v$3 !== _p$._v$3 && className(_el$3, _p$._v$3 = _v$3);
391
- _v$4 !== _p$._v$4 && _el$3.style.setProperty("top", _p$._v$4 = _v$4);
392
- _v$5 !== _p$._v$5 && _el$3.style.setProperty("height", _p$._v$5 = _v$5);
393
- return _p$;
394
- }, {
395
- _v$3: undefined,
396
- _v$4: undefined,
397
- _v$5: undefined
398
- });
399
- return _el$3;
400
- }
401
- }));
402
391
  effect(_p$ => {
403
- const _v$6 = {
392
+ const _v$3 = {
404
393
  [styles$4["Key"]]: true,
405
394
  [styles$4["black"]]: key().isBlack,
406
395
  [styles$4["white"]]: !key().isBlack,
407
396
  [styles$4["down"]]: isDown()
408
397
  },
409
- _v$7 = key().name,
410
- _v$8 = key().number % 12,
411
- _v$9 = `${virtualDimensions().offset - (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0)}px`,
412
- _v$10 = `${virtualDimensions().size + (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0) + (!key().isBlack && previousIsBlack ? virtualDimensions().size / 2 : 0)}px`,
413
- _v$11 = [`0px 0px ${Math.min(virtualDimensions().size / 20, 1)}px ${Math.min(virtualDimensions().size / 50, 1)}px rgba(0, 0, 0, 0.5) ${key().isBlack ? "" : "inset"}`, isDown() && `0px 0px ${Math.min(virtualDimensions().size / 8, 2)}px ${Math.min(virtualDimensions().size / 20, 2)}px rgba(0, 0, 0, 0.5) inset`].filter(item => !!item).join(", ");
414
- _p$._v$6 = classList(_el$2, _v$6, _p$._v$6);
415
- _v$7 !== _p$._v$7 && setAttribute(_el$2, "title", _p$._v$7 = _v$7);
416
- _v$8 !== _p$._v$8 && setAttribute(_el$2, "data-index", _p$._v$8 = _v$8);
417
- _v$9 !== _p$._v$9 && _el$2.style.setProperty("top", _p$._v$9 = _v$9);
418
- _v$10 !== _p$._v$10 && _el$2.style.setProperty("height", _p$._v$10 = _v$10);
419
- _v$11 !== _p$._v$11 && _el$2.style.setProperty("box-shadow", _p$._v$11 = _v$11);
398
+ _v$4 = key().name,
399
+ _v$5 = key().number % 12,
400
+ _v$6 = `${virtualDimensions().offset - virtualDimensions().size * (!key().isBlack ? nextIsBlack ? 1 / 2 : 0 : 0)}px`,
401
+ _v$7 = `${virtualDimensions().size + (!key().isBlack && nextIsBlack ? virtualDimensions().size / 2 : 0) + (!key().isBlack && previousIsBlack ? virtualDimensions().size / 2 : 0)}px`,
402
+ _v$8 = [`0px 0px ${Math.min(virtualDimensions().size / 20, 1)}px ${Math.min(virtualDimensions().size / 50, 1)}px rgba(0, 0, 0, 0.5) ${key().isBlack ? "" : "inset"}`, isDown() && `0px 0px ${Math.min(virtualDimensions().size / 8, 2)}px ${Math.min(virtualDimensions().size / 20, 2)}px rgba(0, 0, 0, 0.5) inset`].filter(item => !!item).join(", ");
403
+ _p$._v$3 = classList(_el$2, _v$3, _p$._v$3);
404
+ _v$4 !== _p$._v$4 && setAttribute(_el$2, "title", _p$._v$4 = _v$4);
405
+ _v$5 !== _p$._v$5 && setAttribute(_el$2, "data-index", _p$._v$5 = _v$5);
406
+ _v$6 !== _p$._v$6 && _el$2.style.setProperty("top", _p$._v$6 = _v$6);
407
+ _v$7 !== _p$._v$7 && _el$2.style.setProperty("height", _p$._v$7 = _v$7);
408
+ _v$8 !== _p$._v$8 && _el$2.style.setProperty("box-shadow", _p$._v$8 = _v$8);
420
409
  return _p$;
421
410
  }, {
411
+ _v$3: undefined,
412
+ _v$4: undefined,
413
+ _v$5: undefined,
422
414
  _v$6: undefined,
423
415
  _v$7: undefined,
424
- _v$8: undefined,
425
- _v$9: undefined,
426
- _v$10: undefined,
427
- _v$11: undefined
416
+ _v$8: undefined
428
417
  });
429
418
  return _el$2;
430
419
  }
@@ -467,72 +456,96 @@ const PianoRollNotes = props => {
467
456
  const verticalViewPort = createMemo(() => useViewPortDimension(context.mode === "keys" ? "vertical" : "verticalTracks"));
468
457
  const horizontalViewPort = createMemo(() => useViewPortDimension("horizontal"));
469
458
  const gridDivisionTicks = createMemo(() => context.ppq * 4 / context.gridDivision);
459
+ const [isDragging, setIsDragging] = createSignal(false);
460
+ const [noteDragMode, setNoteDragMode] = createSignal();
461
+ const [currentNoteIndex, setCurrentNoteIndex] = createSignal(-1);
462
+ const [currentNoteTrackIndex, setCurrentNoteTrackIndex] = createSignal(-1);
463
+ const [diffPosition, setDiffPosition] = createSignal(0);
464
+ const [getInitialNote, setInitialNote] = createSignal();
470
465
  const snapValueToGridIfEnabled = (value, altKey) => context.snapToGrid && !altKey ? Math.round(value / gridDivisionTicks()) * gridDivisionTicks() : value;
471
- const insertOrUpdateNote = event => {
472
- const position = horizontalViewPort().calculatePosition(event.clientX);
473
- const existingNote = currentNote();
474
- const midi = context.mode === "keys" ? 127 - Math.floor(verticalViewPort().calculatePosition(event.clientY)) : existingNote?.midi ?? 60;
475
- const targetTrackIndex = context.mode === "tracks" ? clamp(Math.floor(verticalViewPort().calculatePosition(event.clientY)), 0, context.tracks.length - 1) : context.selectedTrackIndex ?? 0;
476
- const eventPositionTicks = Math.floor(position / gridDivisionTicks()) * gridDivisionTicks();
477
- const velocity = 127;
478
- const ticks = existingNote?.ticks ?? eventPositionTicks;
479
- const durationTicks = existingNote?.ticks ? eventPositionTicks - existingNote?.ticks : gridDivisionTicks();
480
- const note = {
466
+ const calculateNoteDragValues = event => {
467
+ const targetTrackIndex = context.mode === "tracks" ? clamp(Math.floor(verticalViewPort().calculatePosition(event.clientY)), 0, context.tracks.length - 1) : currentNoteTrackIndex() > -1 ? currentNoteTrackIndex() : context.selectedTrackIndex;
468
+ const midi = context.mode === "keys" ? Math.floor(128 - verticalViewPort().calculatePosition(event.clientY)) : getInitialNote()?.midi ?? 60;
469
+ const horiontalPosition = horizontalViewPort().calculatePosition(event.clientX);
470
+ return {
471
+ targetTrackIndex,
481
472
  midi,
482
- ticks,
483
- durationTicks,
484
- velocity
473
+ horiontalPosition
485
474
  };
486
- if (existingNote) {
487
- context.onNoteChange?.(currentNoteTrackIndex(), currentNoteIndex(), note);
488
- return currentNoteIndex();
475
+ };
476
+ const handleMouseMove = mouseMoveEvent => {
477
+ const note = getInitialNote();
478
+ if (!note) return;
479
+ const {
480
+ targetTrackIndex,
481
+ midi,
482
+ horiontalPosition
483
+ } = calculateNoteDragValues(mouseMoveEvent);
484
+ const ticks = snapValueToGridIfEnabled(horiontalPosition - diffPosition(), mouseMoveEvent.altKey);
485
+ const updatedNote = {
486
+ ...note,
487
+ midi,
488
+ ...(noteDragMode() === "move" && {
489
+ ticks
490
+ }),
491
+ ...(noteDragMode() === "trimStart" && {
492
+ ticks: ticks < note.ticks + note.durationTicks ? ticks : note.ticks + note.durationTicks,
493
+ durationTicks: ticks < note.ticks + note.durationTicks ? note.ticks + note.durationTicks - ticks : snapValueToGridIfEnabled(horiontalPosition - note.ticks, mouseMoveEvent.altKey)
494
+ }),
495
+ ...(noteDragMode() === "trimEnd" && {
496
+ ticks: ticks < note.ticks ? ticks : note.ticks,
497
+ durationTicks: ticks < note.ticks ? note.ticks - ticks : snapValueToGridIfEnabled(horiontalPosition - note.ticks, mouseMoveEvent.altKey)
498
+ })
499
+ };
500
+ const previousTrackIndex = currentNoteTrackIndex();
501
+ const previousNoteIndex = currentNoteIndex();
502
+ if (targetTrackIndex === previousTrackIndex) {
503
+ context.onNoteChange?.(previousTrackIndex, previousNoteIndex, updatedNote);
489
504
  } else {
490
- return context.onInsertNote?.(targetTrackIndex, note) ?? -1;
505
+ if (context.onInsertNote) {
506
+ context.onRemoveNote?.(previousTrackIndex, previousNoteIndex);
507
+ const newNoteIndex = context.onInsertNote(targetTrackIndex, updatedNote);
508
+ setCurrentNoteTrackIndex(targetTrackIndex);
509
+ setCurrentNoteIndex(newNoteIndex);
510
+ }
491
511
  }
492
512
  };
493
- const [isDragging, setIsDragging] = createSignal(false);
494
- const [noteDragMode, setNoteDragMode] = createSignal();
495
- const [currentNoteIndex, setCurrentNoteIndex] = createSignal(-1);
496
- const [currentNoteTrackIndex, setCurrentNoteTrackIndex] = createSignal(-1);
497
- const [isMouseDown, setIsMouseDown] = createSignal(false);
498
- const currentNote = createMemo(() => context.tracks[currentNoteTrackIndex()]?.notes[currentNoteIndex()]);
513
+ const stopDragging = () => {
514
+ window.removeEventListener("mousemove", handleMouseMove);
515
+ window.removeEventListener("mouseup", stopDragging);
516
+ setIsDragging(false);
517
+ };
518
+ const startDragging = () => {
519
+ window.addEventListener("mousemove", handleMouseMove);
520
+ window.addEventListener("mouseup", stopDragging);
521
+ };
499
522
  const getClasses = noteDragMode => {
500
523
  return noteDragMode ? [styles$2.Note, styles$2[noteDragMode]] : [styles$2.Note];
501
524
  };
502
525
  return (() => {
503
526
  const _el$ = _tmpl$$5.cloneNode(true);
504
- _el$.$$click = event => {
505
- if (currentNote()) {
506
- setCurrentNoteIndex(-1);
507
- return;
508
- }
509
- if (!event.altKey) return;
510
- insertOrUpdateNote(event);
511
- };
512
- _el$.$$dblclick = event => {
513
- insertOrUpdateNote(event);
514
- };
515
- _el$.$$mouseup = event => {
516
- setIsMouseDown(false);
517
- if (!event.altKey) return;
518
- insertOrUpdateNote(event);
519
- };
520
- _el$.$$mousemove = event => {
521
- if (isDragging()) return;
522
- if (!isMouseDown()) {
523
- setNoteDragMode(undefined);
524
- return;
525
- }
526
- const index = insertOrUpdateNote(event);
527
- setCurrentNoteIndex(index);
528
- };
529
- _el$.$$mousedown = event => {
530
- batch(() => {
531
- setIsMouseDown(true);
532
- const index = insertOrUpdateNote(event);
533
- setCurrentNoteTrackIndex(context.selectedTrackIndex ?? 0);
534
- setCurrentNoteIndex(index);
535
- });
527
+ _el$.$$mousedown = mouseDownEvent => {
528
+ const {
529
+ targetTrackIndex,
530
+ midi,
531
+ horiontalPosition
532
+ } = calculateNoteDragValues(mouseDownEvent);
533
+ const ticks = snapValueToGridIfEnabled(horiontalPosition, mouseDownEvent.altKey);
534
+ const durationTicks = gridDivisionTicks();
535
+ const newNote = {
536
+ midi,
537
+ ticks,
538
+ durationTicks,
539
+ velocity: 100
540
+ };
541
+ const newNoteIndex = context.onInsertNote(targetTrackIndex, newNote);
542
+ setIsDragging(true);
543
+ setCurrentNoteTrackIndex(targetTrackIndex);
544
+ setCurrentNoteIndex(newNoteIndex);
545
+ setInitialNote(newNote);
546
+ setDiffPosition(0);
547
+ setNoteDragMode("trimEnd");
548
+ startDragging();
536
549
  };
537
550
  const _ref$ = props.ref;
538
551
  typeof _ref$ === "function" ? use(_ref$, _el$) : props.ref = _el$;
@@ -561,55 +574,13 @@ const PianoRollNotes = props => {
561
574
  const _el$2 = _tmpl$$5.cloneNode(true);
562
575
  _el$2.$$mousedown = event => {
563
576
  event.stopPropagation();
577
+ const initialPosition = horizontalViewPort().calculatePosition(event.clientX);
578
+ setDiffPosition(noteDragMode() === "trimEnd" ? -(note.ticks + note.durationTicks - initialPosition) : initialPosition - note.ticks);
564
579
  setIsDragging(true);
565
580
  setCurrentNoteIndex(noteIndex());
566
581
  setCurrentNoteTrackIndex(trackIndex());
567
- const initialPosition = horizontalViewPort().calculatePosition(event.clientX);
568
- const diffPosition = initialPosition - note.ticks;
569
- const handleMouseMove = mouseMoveEvent => {
570
- const note = currentNote();
571
- if (!note) return;
572
- const ticks = snapValueToGridIfEnabled(Math.max(horizontalViewPort().calculatePosition(mouseMoveEvent.clientX) - diffPosition, 0), mouseMoveEvent.altKey);
573
- const updatedNote = {
574
- ...note,
575
- ...(noteDragMode() === "move" && context.mode === "keys" && {
576
- midi: Math.round(127 - verticalViewPort().calculatePosition(mouseMoveEvent.clientY))
577
- }),
578
- ...((noteDragMode() === "move" || noteDragMode() === "trimStart") && {
579
- ticks
580
- }),
581
- ...(noteDragMode() === "trimStart" && {
582
- durationTicks: note.durationTicks + note.ticks - ticks
583
- }),
584
- ...(noteDragMode() === "trimEnd" && {
585
- durationTicks: snapValueToGridIfEnabled(horizontalViewPort().calculatePosition(mouseMoveEvent.clientX) - note.ticks, mouseMoveEvent.altKey)
586
- })
587
- };
588
- const previousTrackIndex = currentNoteTrackIndex();
589
- const previousNoteIndex = currentNoteIndex();
590
- const targetTrackIndex = context.mode === "tracks" ? clamp(Math.floor(verticalViewPort().calculatePosition(mouseMoveEvent.clientY)), 0, context.tracks.length - 1) : previousTrackIndex;
591
- if (targetTrackIndex === previousTrackIndex) {
592
- context.onNoteChange?.(previousTrackIndex, previousNoteIndex, updatedNote);
593
- } else {
594
- batch(() => {
595
- if (context.onInsertNote) {
596
- context.onRemoveNote?.(previousTrackIndex, previousNoteIndex);
597
- const newNoteIndex = context.onInsertNote(targetTrackIndex, updatedNote);
598
- setCurrentNoteTrackIndex(targetTrackIndex);
599
- setCurrentNoteIndex(newNoteIndex);
600
- }
601
- });
602
- }
603
- };
604
- const handleMouseUp = () => {
605
- setIsDragging(false);
606
- setCurrentNoteIndex(-1);
607
- setCurrentNoteTrackIndex(-1);
608
- window.removeEventListener("mousemove", handleMouseMove);
609
- window.removeEventListener("mouseup", handleMouseUp);
610
- };
611
- window.addEventListener("mousemove", handleMouseMove);
612
- window.addEventListener("mouseup", handleMouseUp);
582
+ setInitialNote(note);
583
+ startDragging();
613
584
  };
614
585
  _el$2.$$dblclick = event => {
615
586
  event.stopPropagation();
@@ -661,7 +632,7 @@ const PianoRollNotes = props => {
661
632
  return _el$;
662
633
  })();
663
634
  };
664
- delegateEvents(["mousedown", "mousemove", "mouseup", "dblclick", "click"]);
635
+ delegateEvents(["mousedown", "mousemove", "dblclick"]);
665
636
 
666
637
  var css_248z$1 = ".PianoRollGrid-module_PianoRollGrid__tG119 {\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.PianoRollGrid-module_PianoRollGrid-Row__nRMCs {\n position: absolute;\n border-style: solid;\n border-color: gray;\n}\n\n.PianoRollGrid-module_PianoRollGrid-Time__jLz3E {\n position: absolute;\n box-sizing: border-box;\n top: 0px;\n height: 100%;\n border-left-style: solid;\n border-left-width: 0.5px;\n}\n";
667
638
  var styles$1 = {"PianoRollGrid":"PianoRollGrid-module_PianoRollGrid__tG119","PianoRollGrid-Row":"PianoRollGrid-module_PianoRollGrid-Row__nRMCs","PianoRollGrid-Time":"PianoRollGrid-module_PianoRollGrid-Time__jLz3E"};
@@ -900,8 +871,8 @@ const ZoomSliderControl = props => {
900
871
  })();
901
872
  };
902
873
 
903
- var css_248z = ".PianoRollTrackList-module_PianoRollTrackList__pyuxQ {\n position: relative;\n height: 100%;\n flex: 1;\n}\n\n.PianoRollTrackList-module_Track__VZFIg {\n border-width: 0px;\n position: absolute;\n box-sizing: border-box;\n width: 100%;\n border-color: #000;\n border-style: solid;\n border-right-width: 1px;\n border-bottom-width: 1px;\n}\n";
904
- var styles = {"PianoRollTrackList":"PianoRollTrackList-module_PianoRollTrackList__pyuxQ","Track":"PianoRollTrackList-module_Track__VZFIg"};
874
+ var css_248z = ".PianoRollTrackList-module_PianoRollTrackList__-sDf0 {\n position: relative;\n height: 100%;\n flex: 1;\n}\n\n.PianoRollTrackList-module_Track__mZP1K {\n border-width: 0px;\n position: absolute;\n box-sizing: border-box;\n width: 100%;\n border-color: #000;\n border-style: solid;\n border-right-width: 1px;\n border-bottom-width: 1px;\n cursor: \"pointer\";\n background: \"lightgrey\";\n}\n.PianoRollTrackList-module_Track__mZP1K.PianoRollTrackList-module_selected__0b-mf {\n background: \"gray\";\n}";
875
+ var styles = {"PianoRollTrackList":"PianoRollTrackList-module_PianoRollTrackList__-sDf0","Track":"PianoRollTrackList-module_Track__mZP1K","selected":"PianoRollTrackList-module_selected__0b-mf"};
905
876
  styleInject(css_248z);
906
877
 
907
878
  const _tmpl$$2 = /*#__PURE__*/template(`<div></div>`, 2),
@@ -925,29 +896,26 @@ const PianoRollTrackList = () => {
925
896
  const _el$2 = _tmpl$2$1.cloneNode(true),
926
897
  _el$3 = _el$2.firstChild;
927
898
  _el$2.$$click = () => context.onSelectedTrackIndexChange?.(index);
928
- _el$2.style.setProperty("cursor", "pointer");
929
899
  insert(_el$2, index, _el$3);
930
900
  insert(_el$2, () => track().name || "[unnamed track]", null);
931
901
  effect(_p$ => {
932
902
  const _v$ = {
933
- [styles["Track"]]: true
903
+ [styles["Track"]]: true,
904
+ [styles["selected"]]: index === context.selectedTrackIndex
934
905
  },
935
906
  _v$2 = track().name,
936
907
  _v$3 = `${virtualDimensions().offset}px`,
937
- _v$4 = `${virtualDimensions().size}px`,
938
- _v$5 = index === context.selectedTrackIndex ? "gray" : "lightgrey";
908
+ _v$4 = `${virtualDimensions().size}px`;
939
909
  _p$._v$ = classList(_el$2, _v$, _p$._v$);
940
910
  _v$2 !== _p$._v$2 && setAttribute(_el$2, "title", _p$._v$2 = _v$2);
941
911
  _v$3 !== _p$._v$3 && _el$2.style.setProperty("top", _p$._v$3 = _v$3);
942
912
  _v$4 !== _p$._v$4 && _el$2.style.setProperty("height", _p$._v$4 = _v$4);
943
- _v$5 !== _p$._v$5 && _el$2.style.setProperty("background", _p$._v$5 = _v$5);
944
913
  return _p$;
945
914
  }, {
946
915
  _v$: undefined,
947
916
  _v$2: undefined,
948
917
  _v$3: undefined,
949
- _v$4: undefined,
950
- _v$5: undefined
918
+ _v$4: undefined
951
919
  });
952
920
  return _el$2;
953
921
  }
@@ -1032,9 +1000,6 @@ const PianoRoll = allProps => {
1032
1000
  orientation: "vertical",
1033
1001
  dimensionName: "verticalTracks"
1034
1002
  }), _el$3);
1035
- _el$3.style.setProperty("display", "flex");
1036
- _el$3.style.setProperty("width", "30%");
1037
- _el$3.style.setProperty("max-width", "250px");
1038
1003
  insert(_el$3, createComponent(Show, {
1039
1004
  get when() {
1040
1005
  return context.showTrackList;
@@ -1076,7 +1041,16 @@ const PianoRoll = allProps => {
1076
1041
  return context.mode !== "keys";
1077
1042
  }
1078
1043
  }), null);
1079
- effect(() => className(_el$2, styles$5.PianoRollContainer));
1044
+ effect(_p$ => {
1045
+ const _v$ = styles$5.PianoRollContainer,
1046
+ _v$2 = styles$5.PianoRollLeftColumn;
1047
+ _v$ !== _p$._v$ && className(_el$2, _p$._v$ = _v$);
1048
+ _v$2 !== _p$._v$2 && className(_el$3, _p$._v$2 = _v$2);
1049
+ return _p$;
1050
+ }, {
1051
+ _v$: undefined,
1052
+ _v$2: undefined
1053
+ });
1080
1054
  return _el$2;
1081
1055
  })(), createComponent(ZoomSliderControl, {
1082
1056
  orientation: "horizontal",
@@ -1096,19 +1070,15 @@ const PianoRoll = allProps => {
1096
1070
 
1097
1071
  const _tmpl$ = /*#__PURE__*/template(`<div class="PlayHead"></div>`, 2);
1098
1072
  const PlayHead = allProps => {
1099
- const propsWithDefauls = mergeProps({
1100
- playHeadPosition: 0,
1101
- sync: false
1102
- }, allProps);
1103
- const [props, divProps] = splitProps(propsWithDefauls, ["playHeadPosition", "sync", "onPlayHeadPositionChange", "onPositionChange"]);
1104
- const viewPort = useViewPortDimension("horizontal");
1073
+ const [props, divProps] = splitProps(allProps, ["position", "sync", "onPositionChange", "dimensionName"]);
1074
+ const viewPort = useViewPortDimension(props.dimensionName ?? "horizontal");
1105
1075
  createEffect(() => {
1106
1076
  if (!props.sync) return;
1107
1077
  const maxPosition = viewPort.range;
1108
- const newPosition = clamp(props.playHeadPosition - viewPort.range / viewPort.zoom / 2, 0, maxPosition);
1109
- props.onPositionChange?.(newPosition);
1078
+ const newPosition = clamp(props.position - viewPort.range / viewPort.zoom / 2, 0, maxPosition);
1079
+ viewPort.onPositionChange?.(newPosition);
1110
1080
  });
1111
- const leftPosition = createMemo(() => viewPort.calculatePixelOffset(props.playHeadPosition));
1081
+ const leftPosition = createMemo(() => viewPort.calculatePixelOffset(props.position));
1112
1082
  return (() => {
1113
1083
  const _el$ = _tmpl$.cloneNode(true);
1114
1084
  spread(_el$, mergeProps$1(divProps, {
@@ -1130,7 +1100,7 @@ const PlayHead = allProps => {
1130
1100
  clientX
1131
1101
  }) => {
1132
1102
  const newPosition = viewPort.calculatePosition(clientX);
1133
- props.onPlayHeadPositionChange?.(newPosition);
1103
+ props.onPositionChange?.(newPosition);
1134
1104
  };
1135
1105
  const handleMouseUp = () => {
1136
1106
  window.removeEventListener("mousemove", handleMouseMove);