setRoutes method
Validates and changes several connectors with one resolution.
Implementation
EditResult setRoutes(
Iterable<String> ids, {
ConnectorRoute? route,
double? portSpacing,
Map<String, Object?> options = const {},
}) {
final routes = store.diagram.resolver.registry.routes;
if (route != null && !routes.available.contains(route)) {
return const EditResult.denied(
code: DiagramDenialCode.unsupportedOperation,
reason: 'This connector route is not installed.',
);
}
final steps = <ReplaceElementStep>[];
for (final id in ids.toSet()) {
final before = store.state.document.elementById(id);
if (before is! ConnectorElement) {
return EditResult.denied(
code: DiagramDenialCode.unavailableTarget,
reason: 'No connector $id',
);
}
var after = before;
if (route != null && route != before.route) {
after = after.copyWith(
route: route,
controlPoints: const [],
routedPoints: const [],
routeOptions: const {},
);
}
if (portSpacing != null && portSpacing != after.terminalGap) {
after = after.copyWith(
terminalGap: portSpacing,
routedPoints: const [],
);
}
final schema = routes.optionsOf(after.route);
for (final MapEntry(:key, :value) in options.entries) {
final option = schema[key];
final reason = option == null
? 'This route has no option "$key".'
: value == null || option.field.accepts(value)
? null
: 'Route option "$key" is not a valid value.';
if (reason != null) {
return EditResult.denied(
code: DiagramDenialCode.unsupportedOperation,
reason: reason,
);
}
if (after.routeOptions[key] != value) {
after = after
.withRouteOption(key, value)
.copyWith(routedPoints: const []);
}
}
if (after != before) {
steps.add(ReplaceElementStep(before: before, after: after));
}
}
if (steps.isEmpty) return const EditResult.allow();
return store.edits.dispatch(
DiagramTransaction(label: 'Change connector route', steps: steps),
);
}