UNPKG

@selenite/graph-editor

Version:

A graph editor for visual programming, based on rete and svelte.

177 lines (176 loc) 7.17 kB
import { NodeEditor, NodeFactory } from '../editor'; import { isSetup } from './Setup'; import { setupConnections } from './ConnectionSetup'; import { setupArea } from './AreaSetup'; import { TypedSocketsPlugin } from '../plugins/typed-sockets'; import { tick } from 'svelte'; import { contextMenuSetup, } from '../plugins/context-menu-plugin.svelte'; import { gridLinesSetup } from '../plugins/viewport-addons/gridlines'; import { notificationsSetup } from '../plugins/notifications'; import { HistoryPlugin } from '../plugins/history'; import { setupSvelteRender } from '../render'; import { showContextMenu } from '@selenite/commons'; export async function setupGraphEditor(params = {}) { const editor = new NodeEditor(); const factory = new NodeFactory({ editor, xmlSchemas: params.xmlSchemas }); if (params.container) { params = (await setupArea({ editor, factory, ...params })) ?? params; } const areaSetups = []; for (const setup of params.setups ?? []) { // Handle the case where setup is a function if (!isSetup(setup)) { params = (await setup({ editor, factory, ...params })) ?? params; continue; } console.log(`Setting up ${setup.name}`); if (setup.type === undefined || setup.type === 'editor') { params = (await setup.setup({ editor, factory, ...params })) ?? params; } else if (setup.type === 'area') { areaSetups.push(setup.setup); } else { console.error(`Unknown setup type: ${setup.type}`); } } for (const areaSetup of areaSetups) { await areaSetup({ editor, factory, area: factory.getArea() }); } const { AreaExtensions } = await import('rete-area-plugin'); if (params.saveData) factory.loadGraph(params.saveData); await tick(); setTimeout(async () => { if (factory.getArea()) await AreaExtensions.zoomAt(factory.getArea(), editor.getNodes()); }, 0); return { editor, factory }; } export async function setupFullGraphEditor(params = {}) { params.showContextMenu = showContextMenu; return setupGraphEditor({ ...params, setups: [ ...(params.setups ?? []), setupConnections, ({ editor }) => { console.log('Setting up typed sockets plugin'); const typedSocketsPlugin = new TypedSocketsPlugin(); editor.use(typedSocketsPlugin); }, notificationsSetup, // Temporary area { name: 'Test area', type: 'area', setup: ({ area }) => { let resizeObserver = new ResizeObserver((e) => { area.emit({ type: 'resized', data: { event: new Event('resize') } }); }); resizeObserver.observe(area.container); area.addPipe((ctx) => { if (ctx.type === 'pointerdown') { document.body.style.userSelect = 'none'; // document.body.style.pointerEvents = 'none'; } else if (ctx.type === 'pointerup') { document.body.style.userSelect = ''; // document.body.style.pointerEvents = ''; } // if (ctx.type === 'render') { // console.log(ctx.data) // } // console.log(area.elements) return ctx; }); } }, // Arrange async ({ editor, area, factory }) => { if (!area) { console.warn("AreaPlugin is not defined, can't setup auto arrange plugin."); return; } console.log('Setting up auto arrange'); const { AutoArrangePlugin, Presets: ArrangePresets } = await import('rete-auto-arrange-plugin'); const arrange = new AutoArrangePlugin(); arrange.addPreset(ArrangePresets.classic.setup()); area.use(arrange); factory.arrange = arrange; }, // Area extensions async ({ factory, area }) => { if (!area) { console.warn("AreaPlugin is not defined, can't setup area extensions."); return; } console.log('Setting up area extensions'); const { AreaExtensions } = await import('rete-area-plugin'); AreaExtensions.showInputControl(area); }, // Gridlines gridLinesSetup, // History async ({ area, factory }) => { if (!area) { console.warn("AreaPlugin is not defined, can't setup history plugin."); return; } console.log('Setting up history'); const { Presets: HistoryPresets } = await import('rete-history-plugin'); const history = new HistoryPlugin(); history.addPreset(HistoryPresets.classic.setup()); area.use(history); factory.history = history; }, // { // name: 'comments', // type: 'area', // setup: async ({ factory, area }) => { // const { CommentPlugin, CommentExtensions } = await import( // '$graph-editor/plugins/CommentPlugin' // ); // const comment = new CommentPlugin<Schemes, AreaExtra>({ factory }); // if (!factory.selector) { // console.warn('Missing selector'); // return; // } // if (!factory.accumulating) { // console.warn('Missing accumulating'); // return; // } // CommentExtensions.selectable<Schemes, AreaExtra>( // comment, // factory.selector, // factory.accumulating // ); // factory.comment = comment; // area.use(comment); // } // }, contextMenuSetup({ additionalNodeItems: params.additionalNodeItems, showContextMenu: (params_) => { console.debug('showContextMenu', params_); if (!params.showContextMenu) { console.warn('Missing show context menu function'); return; } params.showContextMenu(params_); } }) // new RenderSetup(), // new ContextMenuSetup() ] }); } export async function setupSvelteGraphEditor(params = {}) { return setupFullGraphEditor({ ...params, setups: [...(params.setups ?? []), setupSvelteRender] }); }