feat: implemented user-friendly chord guide editor; added real time chord guide info to the status bar

This commit is contained in:
Xiaohan-Tian
2026-05-29 12:51:58 -07:00
parent 72297cb731
commit cd2938fe15
16 changed files with 1056 additions and 160 deletions
+11 -2
View File
@@ -1,8 +1,10 @@
export type ChordGuideSource = 'Diatonic' | 'Non-Diatonic';
export interface ChordGuideItem {
name: string;
roman: string;
roman?: string;
notes: string[];
source: string;
source: ChordGuideSource;
note: string;
}
@@ -21,3 +23,10 @@ export interface ResolvedChordGuideItem extends ChordGuideItem {
resolvedNotes: string[];
pitchClasses: number[];
}
export type ChordGuideGroupKey = 'major' | 'minor';
export interface ChordGuideCustomConfig {
major: ChordGuideModeDefinition;
minor: ChordGuideModeDefinition;
}
+4 -1
View File
@@ -1,3 +1,4 @@
import type { ChordGuideCustomConfig } from '../ChordGuideTypes';
import { KGConfigStorage } from '../io/KGConfigStorage';
/**
@@ -103,6 +104,7 @@ interface AppConfig {
};
chord_guide: {
chord_definition: string;
custom_items: ChordGuideCustomConfig | null;
};
[key: string]: unknown;
}
@@ -300,7 +302,8 @@ export class ConfigManager {
custom_instructions: ''
},
chord_guide: {
chord_definition: ''
chord_definition: '',
custom_items: null,
}
};
console.log('Using fallback hardcoded config due to load error');
+25
View File
@@ -28,6 +28,8 @@ export class KGPianoRollState {
private currentMatchingChords: number[][] = [];
private currentSelectedChordIndex: number = 0;
private currentChordCursorPitch: number | null = null;
private currentHoveredChordGuideCandidate: ResolvedChordGuideItem | null = null;
private listeners = new Set<() => void>();
private constructor() {
console.log("KGPianoRollState initialized");
@@ -143,6 +145,7 @@ export class KGPianoRollState {
public setCurrentMatchingChords(chords: number[][]): void {
this.currentMatchingChords = chords;
this.emitChange();
}
public getCurrentSelectedChordIndex(): number {
@@ -151,6 +154,7 @@ export class KGPianoRollState {
public setCurrentSelectedChordIndex(index: number): void {
this.currentSelectedChordIndex = index;
this.emitChange();
}
public getCurrentChordCursorPitch(): number | null {
@@ -159,5 +163,26 @@ export class KGPianoRollState {
public setCurrentChordCursorPitch(pitch: number | null): void {
this.currentChordCursorPitch = pitch;
this.emitChange();
}
public getCurrentHoveredChordGuideCandidate(): ResolvedChordGuideItem | null {
return this.currentHoveredChordGuideCandidate;
}
public setCurrentHoveredChordGuideCandidate(candidate: ResolvedChordGuideItem | null): void {
this.currentHoveredChordGuideCandidate = candidate;
this.emitChange();
}
public subscribe(listener: () => void): () => void {
this.listeners.add(listener);
return () => {
this.listeners.delete(listener);
};
}
private emitChange(): void {
this.listeners.forEach((listener) => listener());
}
}