forValue<S> static method

DiagramProperty<Object?, Object?> forValue<S>(
  1. String key,
  2. ValueField field, {
  3. required String label,
  4. required Object? read(
    1. S subject
    ),
  5. String? verb,
  6. DiagramPropertyArgs<S, Object>? args,
  7. S update(
    1. S subject,
    2. Object value
    )?,
  8. DiagramPropertyGroup group = DiagramPropertyGroup.general,
  9. String unit = '',
  10. double? max,
  11. String editLabel(
    1. Object? value
    )?,
})

The property that edits a value declared by field, such as a shape's value or a route's option. read returns the stored value and args or update take the value to store: booleans, numbers, ARGB integers for colors and strings, as the field stores them. A number field's bounds come from the field unless max caps them.

Implementation

static DiagramProperty<Object?, Object?> forValue<S>(
  String key,
  ValueField field, {
  required String label,
  required Object? Function(S subject) read,
  String? verb,
  DiagramPropertyArgs<S, Object>? args,
  S Function(S subject, Object value)? update,
  DiagramPropertyGroup group = DiagramPropertyGroup.general,
  String unit = '',
  double? max,
  String Function(Object? value)? editLabel,
}) {
  String? check(Object value) =>
      field.accepts(value) ? null : 'Enter a valid value';
  return switch (field) {
    BooleanValueField() => DiagramProperty.toggle<S>(
      key,
      label: label,
      group: group,
      read: (subject) => read(subject)! as bool,
      verb: verb,
      args: args,
      update: update,
      editLabel: editLabel,
    ),
    NumberValueField(:final minimum, :final maximum, :final integer) =>
      DiagramProperty.number<S>(
        key,
        label: label,
        group: group,
        read: (subject) => (read(subject)! as num).toDouble(),
        verb: verb,
        args: args == null
            ? null
            : (subject, value) =>
                  args(subject, integer ? value.round() : value),
        update: update == null
            ? null
            : (subject, value) =>
                  update(subject, integer ? value.round() : value),
        check: (value) => check(integer ? value.round() : value),
        min: minimum?.toDouble() ?? -1000000,
        max: max ?? maximum?.toDouble() ?? 1000000,
        unit: unit,
        precision: integer ? 0 : 6,
        style: DiagramNumberStyle.field,
        editLabel: editLabel,
      ),
    ColorValueField() => DiagramProperty.color<S>(
      key,
      label: label,
      group: group,
      read: (subject) => DiagramColor(read(subject)! as int),
      verb: verb,
      args: args == null
          ? null
          : (subject, color) => args(subject, color.argb),
      update: update == null
          ? null
          : (subject, color) => update(subject, color.argb),
      editLabel: editLabel,
    ),
    TextValueField(:final allowedValues?) =>
      DiagramProperty.choice<S, String>(
        key,
        label: label,
        group: group,
        style: DiagramChoiceStyle.menu,
        options: (_) => [
          for (final value in allowedValues)
            DiagramPropertyOption(value, label: value, id: value),
        ],
        read: (subject) => read(subject)! as String,
        verb: verb,
        args: args,
        update: update,
        check: check,
        editLabel: editLabel,
      ),
    TextValueField() => DiagramProperty.text<S>(
      key,
      label: label,
      group: group,
      read: (subject) => read(subject)! as String,
      verb: verb,
      args: args,
      update: update,
      check: check,
      editLabel: editLabel,
    ),
    ObjectValueField() => DiagramProperty.custom<S, Map<String, Object?>>(
      key,
      label: label,
      group: group,
      read: (subject) => read(subject)! as Map<String, Object?>,
      summary: (value) =>
          '${value.length} ${value.length == 1 ? 'field' : 'fields'}',
    ),
    PathValueField() || InkValueField() || ImageValueField() =>
      throw ArgumentError.value(key, 'key', 'has its own editor'),
  };
}