canvasAssetLibraryExtension<TSourceDocument> function
EditorExtension<TSourceDocument>
canvasAssetLibraryExtension<TSourceDocument>({
- required CanvasAssetLibrary library,
- required CanvasAssetLibrarySelectionPresenter presentSelection,
Creates an editor extension that inserts assets selected from library.
The host owns the catalog and selection UI. The extension owns the shared editor behavior after selection:
- persists CanvasAssetLibraryItem.sourceRef, never
thumbnailRef; - preserves the intrinsic aspect ratio for the initial image size;
- places the image at the centre of the artboard;
- inserts through editor history and selects the new node.
The action is hidden when library contains no items.
Implementation
EditorExtension<TSourceDocument> canvasAssetLibraryExtension<TSourceDocument>({
required CanvasAssetLibrary library,
required CanvasAssetLibrarySelectionPresenter presentSelection,
}) {
final hasAssets = library.items.isNotEmpty;
return StaticEditorExtension<TSourceDocument>(
actionSpecs: <EditorActionSpec>[
EditorActionSpec(
id: const EditorActionId('assetLibrary.open'),
section: EditorToolbarSection.add,
labelBuilder: (_) => 'Assets',
iconBuilder: (_) => Icons.collections_outlined,
isEnabled: (_) => hasAssets,
isVisible: (_) => hasAssets,
priority: 85,
invoke: (context) async {
final selected = await presentSelection(
context.buildContext,
library,
);
if (selected == null || !context.buildContext.mounted) {
return;
}
if (selected.sourceRef.trim().isEmpty) {
context.ui.toast('Unable to add asset: missing image source.');
return;
}
final artboard = context.editableScene.artboardSize;
final size = _initialAssetSize(selected);
final nodeId = _nextAssetNodeId();
final assetId = nodeId;
final node = ImageNode(
id: nodeId,
data: ImageData(
assetId: assetId,
size: size,
fit: ImageFit.contain,
align: const Vec2(0.5, 0.5),
),
xf: Transform2D(position: Vec2(artboard.w * 0.5, artboard.h * 0.5)),
);
context.controller.applyEdit(
EditorEdits.updateScene((scene) {
final nextScene = scene.copyWith(
assets: <CanvasAssetId, CanvasImageAsset>{
...scene.assets,
assetId: CanvasImageAsset(
sourceRef: selected.sourceRef,
intrinsicSize: _validIntrinsicSize(selected.intrinsicSize),
),
},
);
return SceneTreeOps.addNode(nextScene, node);
}),
);
context.selectItems([nodeId]);
},
),
],
);
}