feat: added logic to get suitable chords (console log only)
This commit is contained in:
@@ -13,6 +13,7 @@ import { KGPianoRollState } from '../../core/state/KGPianoRollState';
|
||||
import { ConfigManager } from '../../core/config/ConfigManager';
|
||||
import { beatsToBar } from '../../util/midiUtil';
|
||||
import { UpdateRegionCommand } from '../../core/commands';
|
||||
import { getSuitableChords, noteNameToPitchClass } from '../../util/scaleUtil';
|
||||
|
||||
interface PianoRollProps {
|
||||
onClose: () => void;
|
||||
@@ -39,6 +40,9 @@ const PianoRoll: React.FC<PianoRollProps> = ({
|
||||
// Snapping state
|
||||
const [snapping, setSnapping] = useState<string>('NO SNAP');
|
||||
|
||||
// Chord guide state
|
||||
const [chordGuide, setChordGuide] = useState<string>('N');
|
||||
|
||||
// Piano roll state with temporary initial values
|
||||
const [position, setPosition] = useState(initialPosition || { x: 0, y: 0 });
|
||||
|
||||
@@ -303,7 +307,62 @@ const PianoRoll: React.FC<PianoRollProps> = ({
|
||||
console.log(`Selected mode: ${value}`);
|
||||
}
|
||||
}, [setSelectedMode]);
|
||||
|
||||
|
||||
// Handle chord guide selection
|
||||
const handleChordGuideSelect = useCallback((value: string) => {
|
||||
setChordGuide(value);
|
||||
}, []);
|
||||
|
||||
// Update suitable chords whenever chord guide, key signature, or mode changes
|
||||
useEffect(() => {
|
||||
const pianoRollState = KGPianoRollState.instance();
|
||||
|
||||
if (chordGuide === 'N') {
|
||||
// Disabled - clear chord data
|
||||
pianoRollState.setCurrentSuitableChords({});
|
||||
pianoRollState.setCurrentSuitableChordsPitchClasses({});
|
||||
|
||||
if (DEBUG_MODE.PIANO_ROLL) {
|
||||
console.log(`Chord guide disabled - cleared suitable chords`);
|
||||
}
|
||||
} else {
|
||||
// Get suitable chords for the selected function (T/S/D)
|
||||
const functionType = chordGuide as 'T' | 'S' | 'D';
|
||||
const suitableChords = getSuitableChords(keySignature, selectedMode, functionType);
|
||||
|
||||
// Convert note names to pitch classes (ensuring ascending order)
|
||||
const chordsPitchClasses: Record<string, number[]> = {};
|
||||
for (const [chordSymbol, noteNames] of Object.entries(suitableChords)) {
|
||||
const pitchClasses: number[] = [];
|
||||
let previousPitch = -1;
|
||||
|
||||
for (const noteName of noteNames) {
|
||||
let pitchClass = noteNameToPitchClass(noteName);
|
||||
|
||||
// If this pitch is lower than the previous one, add an octave
|
||||
if (previousPitch >= 0 && pitchClass <= previousPitch) {
|
||||
pitchClass += 12;
|
||||
}
|
||||
|
||||
pitchClasses.push(pitchClass);
|
||||
previousPitch = pitchClass;
|
||||
}
|
||||
|
||||
chordsPitchClasses[chordSymbol] = pitchClasses;
|
||||
}
|
||||
|
||||
// Update piano roll state
|
||||
pianoRollState.setCurrentSuitableChords(suitableChords);
|
||||
pianoRollState.setCurrentSuitableChordsPitchClasses(chordsPitchClasses);
|
||||
|
||||
if (DEBUG_MODE.PIANO_ROLL) {
|
||||
console.log(`Chord guide updated: ${chordGuide} (${functionType})`);
|
||||
console.log(`Suitable chords for ${keySignature} in ${selectedMode} mode:`, suitableChords);
|
||||
console.log(`Pitch classes:`, chordsPitchClasses);
|
||||
}
|
||||
}
|
||||
}, [chordGuide, keySignature, selectedMode]);
|
||||
|
||||
// Handler for receiving the setNoteUpdateCounter function from PianoRollContent
|
||||
const handleSetNoteUpdateTrigger = (setNoteFn: React.Dispatch<React.SetStateAction<number>>) => {
|
||||
triggerNoteUpdateRef.current = setNoteFn;
|
||||
@@ -775,6 +834,8 @@ const PianoRoll: React.FC<PianoRollProps> = ({
|
||||
onSnappingSelect={handleSnappingSelect}
|
||||
selectedMode={selectedMode}
|
||||
onModeChange={handleModeSelect}
|
||||
chordGuide={chordGuide}
|
||||
onChordGuideChange={handleChordGuideSelect}
|
||||
blinkButton={blinkButton}
|
||||
/>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
import { FaMousePointer, FaPencilAlt } from 'react-icons/fa';
|
||||
import { KGDropdown } from '../common';
|
||||
import { KGPianoRollState } from '../../core/state/KGPianoRollState';
|
||||
import { KGCore } from '../../core/KGCore';
|
||||
|
||||
interface PianoRollToolbarProps {
|
||||
activeTool: 'pointer' | 'pencil';
|
||||
@@ -13,6 +14,8 @@ interface PianoRollToolbarProps {
|
||||
onSnappingSelect: (value: string) => void;
|
||||
selectedMode: string;
|
||||
onModeChange: (value: string) => void;
|
||||
chordGuide: string;
|
||||
onChordGuideChange: (value: string) => void;
|
||||
blinkButton?: string | null;
|
||||
}
|
||||
|
||||
@@ -26,20 +29,35 @@ const PianoRollToolbar: React.FC<PianoRollToolbarProps> = ({
|
||||
onSnappingSelect,
|
||||
selectedMode,
|
||||
onModeChange,
|
||||
chordGuide,
|
||||
onChordGuideChange,
|
||||
blinkButton = null
|
||||
}) => {
|
||||
return (
|
||||
<div className="piano-roll-toolbar">
|
||||
<div className="toolbar-left">
|
||||
{/* Left section with mode dropdown */}
|
||||
{/* Left section with mode and chord guide dropdowns */}
|
||||
<KGDropdown
|
||||
options={KGPianoRollState.MODE_DATA.map(m => ({ label: m.name, value: m.id }))}
|
||||
options={KGCore.MODE_DATA.map(m => ({ label: m.name, value: m.id }))}
|
||||
value={selectedMode}
|
||||
onChange={(value) => onModeChange(value)}
|
||||
label="Mode"
|
||||
buttonClassName="mode-dropdown"
|
||||
showValueAsLabel={true}
|
||||
/>
|
||||
<KGDropdown
|
||||
options={[
|
||||
{ label: 'Guide: Disabled', value: 'N' },
|
||||
{ label: 'Chord Guide: T', value: 'T' },
|
||||
{ label: 'Chord Guide: S', value: 'S' },
|
||||
{ label: 'Chord Guide: D', value: 'D' }
|
||||
]}
|
||||
value={chordGuide}
|
||||
onChange={(value) => onChordGuideChange(value)}
|
||||
label="Chord"
|
||||
buttonClassName="chord-guide-dropdown"
|
||||
showValueAsLabel={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="toolbar-center">
|
||||
|
||||
Reference in New Issue
Block a user