@selenite/graph-editor
Version:
A graph editor for visual programming, based on rete and svelte.
177 lines (176 loc) • 7.17 kB
JavaScript
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] });
}