# Chart / Image / Object UX

`dev-24.0.0` improves the first Object Layer milestone from placeholder-only behavior toward practical spreadsheet object editing.

## Scope

- Image insertion through Host `OpenFile` callback with `role: 'asset'`.
- `.uspdx` persistence of image payloads as data URLs in `sheet.objects[]`.
- Multi-series chart payload generation from selected table ranges.
- Column and line chart preview rendering.
- Chart context menu actions for refresh and chart-type switching.
- Object z-order commands.
- Object lock/unlock metadata.
- Keyboard nudging with arrow keys when an object is selected.
- Inline TextBox editing by double-clicking the text box.

## Architecture notes

Object data remains outside cell data. The model stores floating objects as workbook metadata, the renderer owns hit testing and interactive editing, and the engine exposes semantic commands. This separation is intentional because future Chart/Image/XLSX drawing support should not disturb formula, filter, sort, merge, or cell-formatting behavior.

## Image insertion policy

The runtime does not open local file pickers directly. `spread.insert.image` asks the Host-supplied `OpenFile` callback for an image asset. Demo pages provide a local callback under `demo/assets/local-file-callbacks.js`; real Hosts can connect the same request to local disk, Google Drive, app storage, or backend storage.

If the callback is not configured, `spread.insert.image` falls back to inserting a placeholder and reports the status.

## Chart refresh

Charts currently store a snapshot derived from `payload.sourceRange`. `spread.object.chart.refresh` rebuilds the snapshot from that source range. This is not yet a full live chart engine, but it gives a stable command seam for later live binding and XLSX chart export.
