public sealed class CurveDrawerA curve editor over the member's own curve.
No guide page documents this yet — the page shows what the code says about itself.
Remarks
⚠ The curve is a reference type, so the editor edits the object the member holds. That makes every key drag a mutation the command stack never saw. What is recorded instead is one command per edit session, holding a copy of the curve from before it: the editor announces changes, and the drawer writes a snapshot back so undo has something to put back.
What "mixed" means for a curve, which had to be decided before any of this could be written. Two curves agree when their keys agree — the same number of them, each at the same time and value with the same tangents and mode. Disagreement is not per-key: two curves with different key counts have no third key to call mixed, so there is nothing between "these are the same curve" and "they are not". The row is mixed or it is not, and a mixed one shows an empty graph rather than one of the curves.
⚠ Compared key by key, and that comparison is no longer this drawer's private opinion. EditProperty.Read used to compare with Equals(object, object), which for a type with no equality is reference identity — and AnimationCurve has none — so two objects holding structurally identical curves read as mixed the moment they were selected together, which is every multi-selection there has ever been: a member initialised = AnimationCurve.Linear() gives each instance its own object. The drawer fixing that for itself left Read, Write, WriteEach and InspectorField.IsModified still comparing by identity behind its back; the answer is OwnedValues' now and all five ask it. Still not Equals on the type: an AnimationCurve is edited in place, has a Changed event, and its keys live in a HashSet inside CurveEditor — giving a mutable model value equality and a hash code is how a selection stops containing the key that is being dragged.
⚠ Every write is a separate copy per object, through WriteEach, and one Write would have been wrong for a reason that has nothing to do with mixing. A single write puts the same instance on every selected object, and twenty objects sharing one curve is not "they all have the same curve" — it is "editing any of them edits all of them", silently, for the rest of the session. Twenty distinct copies is the only reading of "set them all to this" that survives the next edit.
⚠ The member this draws is application code's, and nothing in this repository declares one — which is a decision rather than a gap, and the same one GradientEditor already carries. A sweep of *.cs and *.vxml finds the type, this drawer, its two registrations, the clip conversions and test fixtures, and no [Inspector] or [DataContract] member of that type anywhere. The WaterMaterial at the top of this assembly's README.md is what the row is for: a game type that references Vixen.Ui.Controls.Advanced and writes [Inspector, Curve] public AnimationCurve Amplitude.
⚠ And "make AnimationCurve serialisable so a component can carry one" — #1148's own proposal — is refuted: serialisation is not what stops it, visibility is. A behaviour is read into the component panel through ISceneBehaviorBinder.Copy, which is Restore(Save(…)), so a member the serialiser cannot see draws a foldout with zero rows and no error. But Vixen.Engine does not reference Vixen.Ui.Controls.Advanced at all, so a Behavior cannot name the type whatever attributes it grows. The engine's curve is Vixen.Core.Curves.CurveSample, and CurveEvaluation's own remarks say the two cannot be one type: one is a mutable class that raises events because a person is dragging its keys, the other is a serialised record. AnimationCurveData is that record and already exists.
Methods (3)
public override bool CanDraw(InspectorMember member)Whether this drawer can edit a member.
protected override CurveEditor Build(InspectorField field, UiElement parent)Makes the controls, once.
protected override void Show(InspectorField field, CurveEditor editor, AnimationCurve? value, bool isMixed)
Used by (2)
- DrawerRegistryVixen.Editor.Inspector
- DrawerTestsVixen.Editor.Inspector.Tests