Apologies for the roughness of any code i share, im largely just running tests to see whats possible, there are likely many wrong assumptions and shoddy code as i play.
Ive played with this a little more this morning and realised that the use case of adding a single block from a plugin can be extended to adding multiple prewired blocks with a change to the event listener... e.g.
//-----------------------------------------------------------------------
//-- Unified event listener for plugins to add blocks to the design
//-- Supports both single blocks and multiple connected blocks
//-- Backward compatible with old plugin.addBlock format
//-----------------------------------------------------------------------
iceStudio.bus.events.subscribe('plugin.addConnectedBlocks', function (data) {
if (data && data.blocks && data.blocks.length > 0) {
console.log('Graph service received plugin.addConnectedBlocks event', data);
let blockCells = [];
let allCells = [];
// Create all blocks
data.blocks.forEach(function(blockData) {
if (blockData.type === 'basic.code') {
// Ensure block has position before loading
if (!blockData.position) {
blockData.position = { x: 0, y: 0 };
}
let cell = blockforms.loadBasic(blockData);
blockCells.push(cell);
}
});
// Position blocks horizontally with spacing relative to first block
if (blockCells.length > 0) {
let spacing = 400;
// Set relative positions for all blocks
blockCells.forEach(function(cell, index) {
cell.set('position', {
x: index * spacing,
y: 0
});
});
// First, add the blocks using addDraggableCells (handles positioning, selection, dragging)
self.addDraggableCells(blockCells);
// After blocks are added to graph, create and add wires
if (data.wires && data.wires.length > 0) {
data.wires.forEach(function(wireSpec) {
let sourceBlock = blockCells[wireSpec.source.blockIndex];
let targetBlock = blockCells[wireSpec.target.blockIndex];
if (sourceBlock && targetBlock) {
let sourcePortId = null;
let targetPortId = null;
let sourceRightPorts = sourceBlock.get('rightPorts');
let targetLeftPorts = targetBlock.get('leftPorts');
// Find source port ID
if (sourceRightPorts) {
sourceRightPorts.forEach(function(port) {
if (port.name === wireSpec.source.port) {
sourcePortId = port.id;
}
});
}
// Find target port ID
if (targetLeftPorts) {
targetLeftPorts.forEach(function(port) {
if (port.name === wireSpec.target.port) {
targetPortId = port.id;
}
});
}
if (sourcePortId && targetPortId) {
let wire = new joint.shapes.ice.Wire({
source: { id: sourceBlock.id, port: sourcePortId },
target: { id: targetBlock.id, port: targetPortId }
});
graph.addCell(wire);
}
}
});
}
}
}
});
So you can add multiple blocks and wires in one shot and then drag them to the location.
function addTestBlocks() {
console.log('Adding test connected blocks...');
try {
// Create first block (source) - generates a signal
var block1Data = {
type: 'basic.code',
data: {
code: '// Source block\nassign out = counter[0];',
params: [],
ports: {
in: [],
out: [
{ name: 'out' }
]
}
}
};
// Create second block (sink) - receives the signal
var block2Data = {
type: 'basic.code',
data: {
code: '// Sink block\nassign led = in;',
params: [],
ports: {
in: [
{ name: 'in' }
],
out: [
{ name: 'led' }
]
}
}
};
// Publish event to add connected blocks
if (typeof iceStudio !== 'undefined' && iceStudio.bus && iceStudio.bus.events) {
iceStudio.bus.events.publish('plugin.addConnectedBlocks', {
blocks: [block1Data, block2Data],
wires: [
{
source: { blockIndex: 0, port: 'out' },
target: { blockIndex: 1, port: 'in' }
}
]
});
console.log('Test blocks added successfully');
} else {
console.error('iceStudio event bus not available');
}
} catch (error) {
console.error('Error adding test blocks:', error);
}
}