Preparing search index...

    Module LensStudio:LensBasedEditorView

    Module providing a live lens preview widget for use inside panel plugins.

        // LensBasedEditorView embeds a running Lens inside a plugin panel — use it
    // for visual editors, material previews, animation tools, or any UI that
    // benefits from a live lens preview. Communicate with the lens runtime via
    // postMessage / onMessage; observe lens lifecycle via onStateChanged.
    import * as Ui from 'LensStudio:Ui';
    import { PanelPlugin, Descriptor } from 'LensStudio:PanelPlugin';
    import * as LensBasedEditorView from 'LensStudio:LensBasedEditorView';

    export class MyVisualEditor extends PanelPlugin {
    private root: Ui.Widget | null = null;
    private lensView: LensBasedEditorView.LensBasedEditorView | null = null;
    private connections: Editor.ScopedConnection[] = [];

    static descriptor(): Descriptor {
    const d = new Descriptor();
    d.id = 'com.example.visualeditor';
    d.name = 'Visual Editor';
    d.description = 'Editor with live lens preview';
    d.dependencies = [Editor.Model.IModel, Ui.IGui];
    return d;
    }

    createWidget(parent: Ui.Widget): Ui.Widget {
    this.root = new Ui.Widget(parent);
    const layout = new Ui.BoxLayout();
    layout.setDirection(Ui.Direction.TopToBottom);
    this.root.layout = layout;

    // Create the lens view with InitOptions and add it to the panel.
    const initOptions = new LensBasedEditorView.InitOptions();
    this.lensView = LensBasedEditorView.create(initOptions, this.root);
    this.lensView.setSizePolicy(
    Ui.SizePolicy.Policy.Expanding,
    Ui.SizePolicy.Policy.Expanding,
    );
    layout.addWidget(this.lensView);

    // Input source for the lens (image or video).
    const imageInput = new LensBasedEditorView.ImageInput();
    imageInput.file = new Editor.Path(
    import.meta.resolve('./Resources/preview_background.png'),
    );
    imageInput.fps = 30;
    imageInput.paused = false;

    // Load options point at a packaged editor lens (.zip) and pair it
    // with the input. Set useOverlayOutput so the lens renders into the
    // overlay layer of the host widget.
    const loadOptions = new LensBasedEditorView.LoadOptions();
    loadOptions.lens = new Editor.Path(import.meta.resolve('./EditorLens.zip'));
    loadOptions.input = imageInput;
    loadOptions.useOverlayOutput = true;

    this.lensView.load(loadOptions);

    // Receive messages from the lens runtime (Editor.context.postMessage).
    this.connections.push(
    this.lensView.onMessage.connect((message) => {
    const { type, payload } = message;
    if (type === 'stateChanged') console.log('Lens state:', JSON.parse(payload));
    else if (type === 'error') console.error('Lens error:', payload);
    }),
    );

    // React to lens lifecycle (e.g. send initial state once Running).
    this.connections.push(
    this.lensView.onStateChanged.connect((state) => {
    if (state === LensBasedEditorView.State.Running) {
    this.lensView!.postMessage({
    type: 'init',
    payload: { color: '#ff0000', intensity: 0.8 },
    });
    }
    }),
    );

    return this.root;
    }

    deinit(): void {
    this.connections.forEach((c) => c?.disconnect());
    this.connections = [];
    if (this.lensView) {
    if (this.lensView.isLoaded) this.lensView.unload();
    this.lensView.deleteLater();
    this.lensView = null;
    }
    if (this.root) {
    this.root.deleteLater();
    this.root = null;
    }
    }
    }