Move chord inversion controls to fretboard section
- Remove inversion controls from top control panel - Add button-row style controls in fretboard section: - "Major" toggle button (will add Minor 7th, Major 7th later) - Key selector buttons (all 12 keys, shown when Major is active) - Update JavaScript event handlers for button-based controls - Add inversionChordType to state for future chord type support https://claude.ai/code/session_01VSHtwaMJKL1ZgH33JDcwbY
+76 −35 · 2 files changed
-
index.html+28 −24 -
js/app.js+48 −11
@@ -54,30 +54,6 @@ </div> </div> - <div class="control-group"> - <label>Chord Inversions</label> - <div class="checkbox-container"> - <input type="checkbox" id="showInversionsToggle"> - <span>Show inversions on fretboard</span> - </div> - <div style="margin-top: 8px;"> - <select id="inversionRootNote" style="width: 100%;"> - <option value="C">C Major</option> - <option value="C#">C#/Db Major</option> - <option value="D">D Major</option> - <option value="D#">D#/Eb Major</option> - <option value="E">E Major</option> - <option value="F">F Major</option> - <option value="F#">F#/Gb Major</option> - <option value="G" selected>G Major</option> - <option value="G#">G#/Ab Major</option> - <option value="A">A Major</option> - <option value="A#">A#/Bb Major</option> - <option value="B">B Major</option> - </select> - </div> - </div> - <div class="control-group"> <label>Actions</label> <div style="display: flex; gap: 10px;"> @@ -119,6 +95,34 @@ Notes above the capo are grayed out to indicate they are not playable. </div> + <!-- Chord Inversions Controls --> + <div class="chord-controls no-print" id="inversionControls"> + <div class="chord-control-group"> + <label>Show Inversions</label> + <div class="chord-type-buttons" id="inversionTypeButtons"> + <button class="chord-type-btn" data-type="major">Major</button> + </div> + </div> + + <div class="chord-control-group" id="inversionKeyContainer" style="display: none;"> + <label>Key</label> + <div class="key-buttons" id="inversionKeyButtons"> + <button class="key-btn" data-key="C">C</button> + <button class="key-btn" data-key="C#">C#</button> + <button class="key-btn" data-key="D">D</button> + <button class="key-btn" data-key="D#">D#</button> + <button class="key-btn" data-key="E">E</button> + <button class="key-btn" data-key="F">F</button> + <button class="key-btn" data-key="F#">F#</button> + <button class="key-btn active" data-key="G">G</button> + <button class="key-btn" data-key="G#">G#</button> + <button class="key-btn" data-key="A">A</button> + <button class="key-btn" data-key="A#">A#</button> + <button class="key-btn" data-key="B">B</button> + </div> + </div> + </div> + <div class="fretboard-layout"> <!-- Tuning Selector (Left Side) --> <div class="tuning-selector no-print"> @@ -14,6 +14,7 @@ let state = { // Chord inversion state showInversions: false, inversionRootNote: 'G', + inversionChordType: 'major', // Chord tab state chordTuning: 'Open G', chordKey: 'G', @@ -154,17 +155,37 @@ function setupEventListeners() { populateTuningList(); }); - // Chord inversion controls - document.getElementById('showInversionsToggle').addEventListener('change', (e) => { - state.showInversions = e.target.checked; - saveState(); - renderFretboard(); + // Chord inversion controls (button-based in fretboard section) + document.querySelectorAll('#inversionTypeButtons .chord-type-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + const type = e.target.dataset.type; + const isActive = e.target.classList.contains('active'); + + // Toggle the button + if (isActive) { + e.target.classList.remove('active'); + state.showInversions = false; + document.getElementById('inversionKeyContainer').style.display = 'none'; + } else { + e.target.classList.add('active'); + state.showInversions = true; + state.inversionChordType = type; + document.getElementById('inversionKeyContainer').style.display = 'block'; + } + saveState(); + renderFretboard(); + }); }); - document.getElementById('inversionRootNote').addEventListener('change', (e) => { - state.inversionRootNote = e.target.value; - saveState(); - renderFretboard(); + document.querySelectorAll('#inversionKeyButtons .key-btn').forEach(btn => { + btn.addEventListener('click', (e) => { + // Remove active from all key buttons + document.querySelectorAll('#inversionKeyButtons .key-btn').forEach(b => b.classList.remove('active')); + e.target.classList.add('active'); + state.inversionRootNote = e.target.dataset.key; + saveState(); + renderFretboard(); + }); }); // Fretboard family filter @@ -196,6 +217,7 @@ function resetSettings() { useSolfege: false, showInversions: false, inversionRootNote: 'G', + inversionChordType: 'major', chordTuning: 'Open G', chordKey: 'G', chordTypeFilter: 'all', @@ -217,8 +239,23 @@ function applyStateToUI() { document.getElementById('showNotesToggle').checked = state.showNotes; document.getElementById('solfegeToggle').checked = state.useSolfege || false; document.getElementById('fretboardFamilyFilter').value = state.fretboardFamilyFilter || 'all'; - document.getElementById('showInversionsToggle').checked = state.showInversions || false; - document.getElementById('inversionRootNote').value = state.inversionRootNote || 'G'; + + // Inversion controls (button-based) + const inversionTypeBtn = document.querySelector('#inversionTypeButtons .chord-type-btn[data-type="major"]'); + if (inversionTypeBtn) { + if (state.showInversions) { + inversionTypeBtn.classList.add('active'); + document.getElementById('inversionKeyContainer').style.display = 'block'; + } else { + inversionTypeBtn.classList.remove('active'); + document.getElementById('inversionKeyContainer').style.display = 'none'; + } + } + + // Set active key button + document.querySelectorAll('#inversionKeyButtons .key-btn').forEach(btn => { + btn.classList.toggle('active', btn.dataset.key === (state.inversionRootNote || 'G')); + }); // Chord tab UI const chordTuningSelect = document.getElementById('chordTuningSelect');