-
Notifications
You must be signed in to change notification settings - Fork 165
Description
🐛 Bug Description
The "Save mouse artwork as PNG" button in the Menu component does not respond when clicked. While the button is visible and the underlying export functionality exists in the codebase, clicking the button does nothing.
📋 Steps to Reproduce
- Launch Music Blocks v4
- Enable the
exportDrawingfeature flag - Draw something on the canvas using turtle blocks
- Click the "Save mouse artwork as PNG" button in the menu
- Expected: A filename prompt should appear and the drawing should be saved
- Actual: Nothing happens - no prompt, no download, no error
🎯 Expected Behavior
When the "Save mouse artwork as PNG" button is clicked:
- A prompt should appear asking for a filename (default: "My Project")
- User enters a filename and clicks OK
- The canvas artwork is downloaded as a PNG file
- The file should contain the turtle's drawing
❌ Actual Behavior
- Clicking the button does nothing
- No console errors
- No user feedback
- The canvas artwork cannot be exported
🔍 Root Cause Analysis
The bug exists because the button component is missing the onClick handler. While all the infrastructure is in place:
✅ The exportDrawing() function exists in modules/painter/src/core/sketchP5.ts
✅ The event listener is registered: hearEvent('menu.exportDrawing', exportDrawing)
✅ The button UI is rendered in the Menu component
❌ Missing: The button has no onClick attribute to emit the event
The button code in modules/menu/src/view/components/index.tsx (lines 44-53):
<button
className={`menu-btn ${!props.injected.flags.exportDrawing ? 'menu-btn-hidden' : ''}`}
>
{/* No onClick handler! */}
<p className="menu-btn-label">
<span>{'Save mouse artwork as PNG'}</span>
</p>
<div className="menu-btn-img">
<SImage asset={props.injected.assets['image.icon.exportDrawing']} />
</div>
</button>Compare this to the working Run button (lines 75-85):
<button
className={`menu-btn ${props.states['running'] ? 'menu-btn-hidden' : ''}`}
onClick={() => (props.handlers.run ? props.handlers.run() : undefined)} // ✅ Has onClick!
>
{/* ... */}
</button>🔧 Solution
The fix involves connecting the button to the event system by:
1. Update Type Definitions
File: @types/components/menu.d.ts
Add 'exportDrawing' to the handlers type:
handlers: Partial<Record<'run' | 'stop' | 'reset' | 'exportDrawing', CallableFunction>>;2. Register the Handler
File: modules/menu/src/index.ts
Add the handler setup in the setup() function:
await updateHandler('exportDrawing', () => {
emitEvent('menu.exportDrawing');
});3. Add Event Type Support
File: lib/events/src/index.ts
Add TypeScript overload for the event:
export function emitEvent(event: 'menu.exportDrawing'): void;4. Connect the Button
File: modules/menu/src/view/components/index.tsx
Add the onClick handler to the button:
<button
className={`menu-btn ${!props.injected.flags.exportDrawing ? 'menu-btn-hidden' : ''}`}
onClick={() => (props.handlers.exportDrawing ? props.handlers.exportDrawing() : undefined)}
>
{/* ... */}
</button>✅ Testing Steps
After applying the fix:
- Launch Music Blocks v4
- Ensure
exportDrawingfeature flag is enabled - Create a simple program with turtle graphics (e.g., draw a square)
- Run the program to create artwork on the canvas
- Click the "Save mouse artwork as PNG" button
- Verify a prompt appears asking for filename
- Enter "test" and click OK
- Verify a file named "test.png" is downloaded
- Open the PNG file and verify it contains the turtle artwork
Environment: Music Blocks v4
Browser: Any (not browser-specific)
Severity: Medium (feature completely non-functional)