feat: added metronome feature

This commit is contained in:
Xiaohan-Tian
2026-04-19 17:00:10 -07:00
parent f0a2f06295
commit 0ac39068b2
5 changed files with 184 additions and 3 deletions
+16 -1
View File
@@ -29,6 +29,7 @@ import FileImportModal from './common/FileImportModal';
import OpenProjectModal from './common/OpenProjectModal';
import { clearChatHistoryAndUI } from '../util/chatUtil';
import PianoIcon from './common/icons/PianoIcon';
import MetronomeIcon from './common/icons/MetronomeIcon';
import { ConfigManager } from '../core/config/ConfigManager';
const Toolbar: React.FC = () => {
@@ -42,7 +43,7 @@ const Toolbar: React.FC = () => {
barWidthMultiplier, setBarWidthMultiplier,
isLooping, toggleLoop,
canUndo, canRedo, undoDescription, redoDescription, undo, redo,
toggleChatBox, toggleSettings, toggleKGOnePanel, showKGOnePanel, cleanupProjectState,
toggleChatBox, toggleSettings, toggleKGOnePanel, showKGOnePanel, cleanupProjectState, toggleMetronome, isMetronomeEnabled,
// Piano roll state/actions
showPianoRoll, setShowPianoRoll, activeRegionId, setActiveRegionId,
// Selection state
@@ -858,6 +859,13 @@ const Toolbar: React.FC = () => {
}
};
const handleMetronomeToggle = () => {
toggleMetronome();
if (DEBUG_MODE.TOOLBAR) {
console.log('Metronome toggled');
}
};
return (
<>
<div className="toolbar">
@@ -949,6 +957,13 @@ const Toolbar: React.FC = () => {
<FaSync />
</button>
<div className="toolbar-separator"></div>
<button
title="Metronome"
className={`tool-button ${isMetronomeEnabled ? 'active' : ''}`}
onClick={handleMetronomeToggle}
>
<MetronomeIcon />
</button>
<button title="Piano" onClick={handlePianoButtonClick}><PianoIcon /></button>
{/* <button title="Record"><FaCircle className="record-btn" /></button>
<button title="Metronome">🎵</button> */}
@@ -0,0 +1,41 @@
import React from 'react';
type MetronomeIconProps = React.SVGProps<SVGSVGElement>;
/**
* MetronomeIcon metronome silhouette in a Font Awesome-like solid style
* - Uses currentColor
* - Scales with font size (1em)
*/
const MetronomeIcon: React.FC<MetronomeIconProps> = (props) => (
<svg
viewBox="0 0 512 512"
width="1em"
height="1em"
fill="currentColor"
aria-hidden="true"
focusable="false"
{...props}
>
{/*
Trapezoidal body with hollow interior, pendulum arm, and weight.
fillRule=evenodd: regions covered by an odd number of sub-paths are filled.
- Outer trapezoid: 1 crossing → filled (solid walls)
- Inner hole: 2 crossings → transparent
- Pendulum: 3 crossings → filled (visible inside hole)
- Weight: 3 crossings → filled (visible inside hole, no overlap with pendulum)
*/}
<path
fillRule="evenodd"
clipRule="evenodd"
d="
M 208 80 L 304 80 L 432 464 L 80 464 Z
M 226 112 L 286 112 L 396 432 L 116 432 Z
M 250 112 L 262 112 L 244 330 L 232 330 Z
M 222 330 L 264 330 L 260 362 L 226 362 Z
"
/>
</svg>
);
export default MetronomeIcon;