Table of Contents

Class CurveEditor

Namespace
PluginUI
Assembly
PluginUI.dll

Multi-segment envelope / LFO shape editor (MSEG, as in Serum or Vital): draggable breakpoints joined by curved segments, grid snapping, play cursor, and exact evaluation of the shape for the audio engine (Evaluate(double)).

public class CurveEditor : Control
Inheritance
CurveEditor
Inherited Members

Remarks

Mouse. Drag a point to move it (the first and last points keep their position when LockEndpoints is set); double-click on the background to add a point, on a point to delete it; drag the small handle in the middle of a segment vertically to bend it. Points snap to the grid unless Shift is held (SnapToGrid).

Curvature. A segment with curvature c is (e^(k·t) − 1) / (e^k − 1) with k = 8c: smooth exponential-like shapes, exactly reproduced by Evaluate(double).

Audio thread. Copy Points (for example into an immutable array published through a volatile field) after each CurveChanged, and evaluate the copy with Evaluate(IReadOnlyList<CurvePoint>, double).

Constructors

CurveEditor()

Creates a curve editor with a triangle shape.

public CurveEditor()

Properties

CurveColor

Curve color (null = theme accent).

public Color? CurveColor { get; set; }

Property Value

Color?

DefaultSize

Natural size used when no explicit size is given.

protected override Size DefaultSize { get; }

Property Value

Size

Filled

Fills the area below the curve.

public bool Filled { get; set; }

Property Value

bool

GridX

Vertical grid divisions (0 = none); also the snapping step.

public int GridX { get; set; }

Property Value

int

GridY

Horizontal grid divisions (0 = none); also the snapping step.

public int GridY { get; set; }

Property Value

int

IsBipolar

Draws a center line and labels values from −1 to +1 (LFO shapes).

public bool IsBipolar { get; set; }

Property Value

bool

LockEndpoints

Keeps the first point at X = 0 and the last at X = 1.

public bool LockEndpoints { get; set; }

Property Value

bool

MaxPoints

Maximum number of points.

public int MaxPoints { get; set; }

Property Value

int

PlayPosition

Play cursor position in [0, 1] (NaN = hidden).

public double PlayPosition { get; set; }

Property Value

double

PlayPositionSource

Function polled every frame for the play cursor.

[Browsable(false)]
public Func<double>? PlayPositionSource { get; set; }

Property Value

Func<double>

Points

The breakpoints, sorted by X (read-only view; edit with SetPoints(IEnumerable<CurvePoint>) or the mouse).

[Browsable(false)]
public IReadOnlyList<CurvePoint> Points { get; }

Property Value

IReadOnlyList<CurvePoint>

SnapToGrid

Snaps dragged points to the grid (hold Shift to move freely).

public bool SnapToGrid { get; set; }

Property Value

bool

Methods

Evaluate(IReadOnlyList<CurvePoint>, double)

Value of a shape at x (usable on a copy of Points on the audio thread).

public static double Evaluate(IReadOnlyList<CurvePoint> points, double x)

Parameters

points IReadOnlyList<CurvePoint>

Points sorted by X.

x double

Position in [0, 1].

Returns

double

Value in [0, 1] (0 for an empty list).

Evaluate(double)

Value of the shape at x (0..1).

public double Evaluate(double x)

Parameters

x double

Position in [0, 1].

Returns

double

Value in [0, 1].

OnAttached()

Called when the element joins a host (subscribe to external events here).

protected override void OnAttached()

OnCaptureLost()

The mouse capture was lost without a button release.

protected override void OnCaptureLost()

OnDetached()

Called when the element leaves its host (unsubscribe here).

protected override void OnDetached()

OnMouseDown(MouseEventArgs)

Mouse button pressed over the element (or captured).

protected override void OnMouseDown(MouseEventArgs e)

Parameters

e MouseEventArgs

OnMouseMove(MouseEventArgs)

Mouse moved over the element (or captured).

protected override void OnMouseMove(MouseEventArgs e)

Parameters

e MouseEventArgs

OnMouseUp(MouseEventArgs)

Mouse button released.

protected override void OnMouseUp(MouseEventArgs e)

Parameters

e MouseEventArgs

RenderVector(DrawingContext, Rect, VectorStyle)

Vector rendering of the widget area.

protected override void RenderVector(DrawingContext dc, Rect widget, VectorStyle style)

Parameters

dc DrawingContext
widget Rect
style VectorStyle

SetPoints(IEnumerable<CurvePoint>)

Replaces all points (sorted by X; values clamped; at least two points).

public void SetPoints(IEnumerable<CurvePoint> points)

Parameters

points IEnumerable<CurvePoint>

The new points.

Exceptions

ArgumentException

Fewer than two points.

Shape(double, double)

Curvature warp of a normalized segment position.

public static double Shape(double t, double curvature)

Parameters

t double

Position inside the segment, 0..1.

curvature double

Curvature, −1..1.

Returns

double

Warped position, 0..1.

Events

CurveChanged

Raised after the user changed the shape (or after SetPoints(IEnumerable<CurvePoint>)).

public event Action<CurveEditor>? CurveChanged

Event Type

Action<CurveEditor>