tooll3--t3
126 行
4.1 KiB
C#
126 行
4.1 KiB
C#
using ImGuiNET;
|
|
using T3.Editor.Gui.Interaction;
|
|
using T3.Editor.Gui.Styling;
|
|
using T3.Editor.Gui.Windows.TimeLine.Raster;
|
|
|
|
namespace T3.Editor.Gui.UiHelpers;
|
|
|
|
internal sealed class CurvePlotCanvas
|
|
{
|
|
internal CurvePlotCanvas(int resolution = 500)
|
|
{
|
|
_sampleCount = resolution;
|
|
_graphValues = new float[_sampleCount];
|
|
_graphPoints = new Vector2[_sampleCount];
|
|
}
|
|
|
|
internal void Draw(float value)
|
|
{
|
|
var dl = ImGui.GetWindowDrawList();
|
|
var min = float.PositiveInfinity;
|
|
var max = float.NegativeInfinity;
|
|
|
|
foreach (var v in _graphValues)
|
|
{
|
|
if (v > max)
|
|
max = v;
|
|
|
|
if (v < min)
|
|
min = v;
|
|
}
|
|
|
|
var padding = (max - min) * 0.2f;
|
|
if (padding < 0.001f)
|
|
padding = 0.05f;
|
|
min -= padding;
|
|
max += padding;
|
|
|
|
|
|
if (ImGui.IsWindowHovered() && ImGui.IsMouseClicked(ImGuiMouseButton.Left))
|
|
{
|
|
_paused = !_paused;
|
|
}
|
|
|
|
if (!ImGui.IsWindowFocused())
|
|
{
|
|
_paused = false;
|
|
}
|
|
|
|
if (!_paused)
|
|
{
|
|
_canvas.SetScopeToCanvasArea(new ImRect(0, min, 1, max), flipY: true);
|
|
_lastValue = value;
|
|
}
|
|
|
|
_canvas.UpdateCanvas(out _);
|
|
dl.PushClipRect(_canvas.WindowPos, _canvas.WindowPos + _canvas.WindowSize, true);
|
|
|
|
_raster.Draw(_canvas);
|
|
|
|
if (!_paused && float.IsFinite(value) && !float.IsInfinity(value) && !float.IsNaN(value))
|
|
{
|
|
_graphValues[_sampleOffset] = value;
|
|
_sampleOffset = (_sampleOffset + 1) % _sampleCount;
|
|
}
|
|
|
|
var maxLength = Math.Max((int)ImGui.GetWindowSize().X, 10);
|
|
var shownSampleCount = Math.Min(_sampleCount, maxLength);
|
|
var startIndex = Math.Max(0,_sampleCount - shownSampleCount);
|
|
|
|
var x = +_canvas.WindowPos.X;
|
|
var dx = (_canvas.WindowSize.X - 20) / shownSampleCount;
|
|
for (var index = startIndex; index < _graphValues.Length; index++)
|
|
{
|
|
var v = _graphValues[(index + _sampleOffset) % _sampleCount];
|
|
_graphPoints[index] = new Vector2(
|
|
(int)x,
|
|
(int)_canvas.TransformY(v));
|
|
x += dx;
|
|
}
|
|
|
|
dl.AddPolyline(ref _graphPoints[startIndex],
|
|
shownSampleCount ,
|
|
UiColors.Text.Fade(0.3f),
|
|
ImDrawFlags.None,
|
|
1);
|
|
dl.AddCircleFilled(_graphPoints[_sampleCount - 1], 3, UiColors.Gray);
|
|
|
|
var windowHeight = ImGui.GetWindowSize().Y / T3Ui.UiScaleFactor;
|
|
var font = windowHeight switch
|
|
{
|
|
< 100 => Fonts.FontSmall,
|
|
< 200 => Fonts.FontNormal,
|
|
_ => Fonts.FontLarge,
|
|
};
|
|
|
|
var valueAsString = $"{_lastValue:G5}";
|
|
dl.AddText(font,
|
|
font.FontSize,
|
|
_canvas.WindowPos
|
|
+ new Vector2(_canvas.WindowSize.X - font.FontSize*5,
|
|
_canvas.WindowSize.Y * 0.5f - font.FontSize / 2),
|
|
UiColors.Text,
|
|
valueAsString);
|
|
|
|
dl.PopClipRect();
|
|
}
|
|
|
|
public void Reset(float clearValue = 0)
|
|
{
|
|
for (var index = 0; index < _sampleCount; index++)
|
|
{
|
|
_graphValues[index] = clearValue;
|
|
}
|
|
}
|
|
|
|
private readonly float[] _graphValues;
|
|
private readonly Vector2[] _graphPoints;
|
|
private int _sampleOffset;
|
|
private readonly int _sampleCount;
|
|
|
|
private bool _paused;
|
|
private float _lastValue;
|
|
|
|
private readonly HorizontalRaster _raster = new();
|
|
private readonly ScalableCanvas _canvas = new CurrentGraphSubCanvas { FillMode = ScalableCanvas.FillModes.FillAvailableContentRegion };
|
|
} |