Skip to content

[BUG] : save work as png button does not work #482

@Nirvanjha2004

Description

@Nirvanjha2004

🐛 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

  1. Launch Music Blocks v4
  2. Enable the exportDrawing feature flag
  3. Draw something on the canvas using turtle blocks
  4. Click the "Save mouse artwork as PNG" button in the menu
  5. Expected: A filename prompt should appear and the drawing should be saved
  6. Actual: Nothing happens - no prompt, no download, no error

🎯 Expected Behavior

When the "Save mouse artwork as PNG" button is clicked:

  1. A prompt should appear asking for a filename (default: "My Project")
  2. User enters a filename and clicks OK
  3. The canvas artwork is downloaded as a PNG file
  4. 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:

  1. Launch Music Blocks v4
  2. Ensure exportDrawing feature flag is enabled
  3. Create a simple program with turtle graphics (e.g., draw a square)
  4. Run the program to create artwork on the canvas
  5. Click the "Save mouse artwork as PNG" button
  6. Verify a prompt appears asking for filename
  7. Enter "test" and click OK
  8. Verify a file named "test.png" is downloaded
  9. 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions