ShapeRegistry constructor

ShapeRegistry(
  1. DiagramExtensionRegistry extensions
)

Implementation

ShapeRegistry(DiagramExtensionRegistry extensions)
  : arrowheads = DiagramArrowheadRegistry(extensions.arrowheads.values),
    portShapes = DiagramPortShapeRegistry(extensions.portShapes.values),
    routes = extensions.routes,
    contentProviders = extensions.contentLayouts,
    connectorTypes = extensions.connectors,
    textTypes = extensions.textElements,
    _definitions = _validatedDefinitions(extensions.shapes.values) {
  for (final type in connectorTypes.keys) {
    if (_definitions.containsKey(type) || textTypes.containsKey(type)) {
      throw ArgumentError('Conflicting connector type: $type');
    }
  }
  for (final type in textTypes.keys) {
    if (_definitions.containsKey(type)) {
      throw ArgumentError('Conflicting text type: $type');
    }
  }
  // Every text a shape, text element or connector label holds is an
  // installed text type, which brings its codec, verbs and tool.
  void requireText(DiagramTextDefinition text, String owner) {
    if (!textTypes.containsKey(text.type)) {
      throw ArgumentError(
        '$owner holds ${text.type} text, which no installed extension '
        'provides. Install the extension that contributes the '
        '${text.type} text type.',
      );
    }
  }

  for (final shape in _definitions.values) {
    for (final layer in shape.expandedLayers) {
      switch (layer) {
        case ShapeTextLayerDefinition(:final slotId, :final textType):
          requireText(textType, 'Shape ${shape.type} (slot $slotId)');
        case ShapeContentLayerDefinition(:final contentType):
          if (!contentProviders.containsKey(contentType)) {
            throw ArgumentError(
              'Shape ${shape.type} requires content provider $contentType',
            );
          }
          for (final text in layer.texts) {
            requireText(text, 'Shape ${shape.type} (slot ${layer.slotId})');
          }
        default:
      }
    }
  }
  for (final text in textTypes.values) {
    for (final layer in text.layers.whereType<ShapeTextLayerDefinition>()) {
      requireText(layer.textType, 'Text ${text.type}');
    }
  }
  for (final connector in connectorTypes.values) {
    if (connector.labeling case final labeling?) {
      requireText(labeling.textType, 'Connector ${connector.type} labels');
    }
  }
}