timeline is dpi scaled

This commit is contained in:
4sval
2023-03-04 13:03:57 +01:00
parent e44a6a032f
commit 3f6e46ef82
6 changed files with 67 additions and 58 deletions

View File

@@ -61,9 +61,9 @@ public class ImGuiController : IDisposable
// ImGui.LoadIniSettingsFromDisk(_iniPath); // ImGui.LoadIniSettingsFromDisk(_iniPath);
var io = ImGui.GetIO(); var io = ImGui.GetIO();
FontNormal = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeui.ttf", 16*DpiScale); FontNormal = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeui.ttf", 16 * DpiScale);
FontBold = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeuib.ttf", 16*DpiScale); FontBold = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeuib.ttf", 16 * DpiScale);
FontSemiBold = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\seguisb.ttf", 16*DpiScale); FontSemiBold = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\seguisb.ttf", 16 * DpiScale);
io.BackendFlags |= ImGuiBackendFlags.RendererHasVtxOffset; io.BackendFlags |= ImGuiBackendFlags.RendererHasVtxOffset;
io.ConfigFlags |= ImGuiConfigFlags.NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags.NavEnableKeyboard;

View File

@@ -90,14 +90,13 @@ public class CUE4ParseViewModel : ViewModel
{ {
return Application.Current.Dispatcher.Invoke(delegate return Application.Current.Dispatcher.Invoke(delegate
{ {
float dpiScale = ImGuiController.GetDpiScale();
return _snooper ??= new Snooper( return _snooper ??= new Snooper(
new GameWindowSettings { RenderFrequency = Snooper.GetMaxRefreshFrequency() }, new GameWindowSettings { RenderFrequency = Snooper.GetMaxRefreshFrequency() },
new NativeWindowSettings new NativeWindowSettings
{ {
Size = new OpenTK.Mathematics.Vector2i( Size = new OpenTK.Mathematics.Vector2i(
Convert.ToInt32(SystemParameters.MaximizedPrimaryScreenWidth * .75 * dpiScale), Convert.ToInt32(SystemParameters.MaximizedPrimaryScreenWidth * .75 * ImGuiController.GetDpiScale()),
Convert.ToInt32(SystemParameters.MaximizedPrimaryScreenHeight * .85 * dpiScale)), Convert.ToInt32(SystemParameters.MaximizedPrimaryScreenHeight * .85 * ImGuiController.GetDpiScale())),
NumberOfSamples = Constants.SAMPLES_COUNT, NumberOfSamples = Constants.SAMPLES_COUNT,
WindowBorder = WindowBorder.Resizable, WindowBorder = WindowBorder.Resizable,
Flags = ContextFlags.ForwardCompatible, Flags = ContextFlags.ForwardCompatible,

View File

@@ -108,6 +108,24 @@ public class Animation : IDisposable
{ {
s.Renderer.Options.SelectAnimation(i); s.Renderer.Options.SelectAnimation(i);
} }
Popup(s, saver, i);
drawList.AddRectFilled(p1, p2, IsSelected ? 0xFF48B048 : 0xFF175F17, 5.0f, ImDrawFlags.RoundCornersTop);
for (int j = 0; j < Sequences.Length; j++)
{
Sequences[j].DrawSequence(drawList, fontPtr, timelineP0.X, p2, timeStep, timeRatio, t, IsSelected);
}
ImGui.SetCursorScreenPos(treeP0 with { Y = p1.Y });
if (ImGui.Selectable(name, s.Renderer.Options.SelectedAnimation == i, ImGuiSelectableFlags.SpanAllColumns, new Vector2(p1.X - treeP0.X, timeStep.Y - t - t)))
{
s.Renderer.Options.SelectAnimation(i);
}
Popup(s, saver, i);
}
private void Popup(Snooper s, Save saver, int i)
{
SnimGui.Popup(() => SnimGui.Popup(() =>
{ {
s.Renderer.Options.SelectAnimation(i); s.Renderer.Options.SelectAnimation(i);
@@ -138,17 +156,5 @@ public class Animation : IDisposable
ImGui.Separator(); ImGui.Separator();
if (ImGui.MenuItem("Copy Path to Clipboard")) ImGui.SetClipboardText(Path); if (ImGui.MenuItem("Copy Path to Clipboard")) ImGui.SetClipboardText(Path);
}); });
drawList.AddRectFilled(p1, p2, IsSelected ? 0xFF48B048 : 0xFF175F17, 5.0f, ImDrawFlags.RoundCornersTop);
for (int j = 0; j < Sequences.Length; j++)
{
Sequences[j].DrawSequence(drawList, fontPtr, timelineP0.X, p2, timeStep, timeRatio, t, IsSelected);
}
ImGui.SetCursorScreenPos(treeP0 with { Y = p1.Y });
if (ImGui.Selectable(name, s.Renderer.Options.SelectedAnimation == i, ImGuiSelectableFlags.SpanAllColumns, new Vector2(p1.X - treeP0.X, timeStep.Y - t - t)))
{
s.Renderer.Options.SelectAnimation(i);
}
} }
} }

View File

@@ -42,7 +42,7 @@ public class Sequence
drawList.AddLine(new Vector2(q2.X, q1.Y), q2, lineColor, 1.0f); drawList.AddLine(new Vector2(q2.X, q1.Y), q2, lineColor, 1.0f);
if (IsAdditive) if (IsAdditive)
drawList.AddText(fontPtr, 12, new Vector2(q1.X + t, q1.Y + halfThickness), animSelected ? 0xFFFFFFFF : 0x50FFFFFF, "Is Additive"); drawList.AddText(fontPtr, 12 * ImGui.GetWindowDpiScale(), new Vector2(q1.X + t, q1.Y + halfThickness), animSelected ? 0xFFFFFFFF : 0x50FFFFFF, "Is Additive");
drawList.PopClipRect(); drawList.PopClipRect();
} }

View File

@@ -55,66 +55,67 @@ public class TimeTracker : IDisposable
Reset(); Reset();
} }
private const float _margin = 5.0f;
private const float _thickness = 2.0f;
private const float _timeHeight = 10.0f;
private float _timeBarHeight => _timeHeight * 2.0f;
private readonly Vector2 _timeStep = new (50, 25);
private readonly Vector2 _buttonSize = new (14.0f);
private readonly string[] _icons = { "tl_forward", "tl_pause", "tl_rewind" }; private readonly string[] _icons = { "tl_forward", "tl_pause", "tl_rewind" };
public void ImGuiTimeline(Snooper s, Save saver, Dictionary<string, Texture> icons, List<Animation> animations, Vector2 outliner, ImFontPtr fontPtr) public void ImGuiTimeline(Snooper s, Save saver, Dictionary<string, Texture> icons, List<Animation> animations, Vector2 outliner, ImFontPtr fontPtr)
{ {
var dpiScale = ImGui.GetWindowDpiScale();
var thickness = 2.0f * dpiScale;
var buttonWidth = 14.0f * dpiScale;
var timeHeight = 10.0f * dpiScale;
var timeBarHeight = timeHeight * 2.0f;
var timeStep = new Vector2(50 * dpiScale, 25 * dpiScale);
var treeP0 = ImGui.GetCursorScreenPos(); var treeP0 = ImGui.GetCursorScreenPos();
var canvasSize = ImGui.GetContentRegionAvail(); var canvasSize = ImGui.GetContentRegionAvail();
var canvasMaxY = MathF.Max(canvasSize.Y, _timeBarHeight + _timeStep.Y * animations.Count); var canvasMaxY = MathF.Max(canvasSize.Y, timeBarHeight + timeStep.Y * animations.Count);
ImGui.BeginChild("timeline_child", canvasSize with { Y = canvasMaxY }); ImGui.BeginChild("timeline_child", canvasSize with { Y = canvasMaxY });
var timelineP1 = new Vector2(treeP0.X + canvasSize.X, treeP0.Y + canvasMaxY); var timelineP1 = new Vector2(treeP0.X + canvasSize.X, treeP0.Y + canvasMaxY);
var treeP1 = timelineP1 with { X = treeP0.X + outliner.X }; var treeP1 = timelineP1 with { X = treeP0.X + outliner.X };
var timelineP0 = treeP0 with { X = treeP1.X + _thickness }; var timelineP0 = treeP0 with { X = treeP1.X + thickness };
var timelineSize = timelineP1 - timelineP0; var timelineSize = timelineP1 - timelineP0;
var timeRatio = timelineSize / MaxElapsedTime; var timeRatio = timelineSize / MaxElapsedTime;
var drawList = ImGui.GetWindowDrawList(); var drawList = ImGui.GetWindowDrawList();
drawList.PushClipRect(treeP0, timelineP1, true); drawList.PushClipRect(treeP0, timelineP1, true);
drawList.AddRectFilled(treeP0, treeP1, 0xFF1F1C1C); drawList.AddRectFilled(treeP0, treeP1, 0xFF1F1C1C);
drawList.AddRectFilled(timelineP0, timelineP1 with { Y = timelineP0.Y + _timeBarHeight }, 0xFF141414); drawList.AddRectFilled(timelineP0, timelineP1 with { Y = timelineP0.Y + timeBarHeight }, 0xFF141414);
drawList.AddRectFilled(timelineP0 with { Y = timelineP0.Y + _timeBarHeight }, timelineP1, 0xFF242424); drawList.AddRectFilled(timelineP0 with { Y = timelineP0.Y + timeBarHeight }, timelineP1, 0xFF242424);
drawList.AddLine(new Vector2(treeP1.X, treeP0.Y), treeP1, 0xFF504545, _thickness); drawList.AddLine(new Vector2(treeP1.X, treeP0.Y), treeP1, 0xFF504545, thickness);
drawList.AddLine(treeP0 with { Y = timelineP0.Y + _timeBarHeight }, timelineP1 with { Y = timelineP0.Y + _timeBarHeight }, 0x50504545, _thickness); drawList.AddLine(treeP0 with { Y = timelineP0.Y + timeBarHeight }, timelineP1 with { Y = timelineP0.Y + timeBarHeight }, 0x50504545, thickness);
// adding margin // adding margin
treeP0.X += _margin; var margin = 5.0f * dpiScale;
treeP1.X -= _margin; treeP0.X += margin;
treeP1.X -= margin;
// control buttons // control buttons
for (int i = 0; i < _icons.Length; i++) for (int i = 0; i < _icons.Length; i++)
{ {
var x = _buttonSize.X * 2.0f * i; var x = buttonWidth * 2.0f * i;
ImGui.SetCursorScreenPos(treeP0 with { X = treeP1.X - x - _buttonSize.X * 2.0f + _thickness }); ImGui.SetCursorScreenPos(treeP0 with { X = treeP1.X - x - buttonWidth * 2.0f + thickness });
if (ImGui.ImageButton($"timeline_actions_{_icons[i]}", icons[i == 1 ? IsPaused ? "tl_play" : "tl_pause" : _icons[i]].GetPointer(), _buttonSize)) if (ImGui.ImageButton($"timeline_actions_{_icons[i]}", icons[i == 1 ? IsPaused ? "tl_play" : "tl_pause" : _icons[i]].GetPointer(), new Vector2(buttonWidth)))
{ {
switch (i) switch (i)
{ {
case 0: case 0:
SafeSetElapsedTime(ElapsedTime + _timeStep.X / timeRatio.X); SafeSetElapsedTime(ElapsedTime + timeStep.X / timeRatio.X);
break; break;
case 1: case 1:
IsPaused = !IsPaused; IsPaused = !IsPaused;
break; break;
case 2: case 2:
SafeSetElapsedTime(ElapsedTime - _timeStep.X / timeRatio.X); SafeSetElapsedTime(ElapsedTime - timeStep.X / timeRatio.X);
break; break;
} }
} }
} }
drawList.AddText(treeP0 with { Y = treeP0.Y + _thickness }, 0xA0FFFFFF, $"{ElapsedTime:F1}/{MaxElapsedTime:F1} seconds"); drawList.AddText(treeP0 with { Y = treeP0.Y + thickness }, 0xA0FFFFFF, $"{ElapsedTime:F1}/{MaxElapsedTime:F1} seconds");
ImGui.SetCursorScreenPos(timelineP0); ImGui.SetCursorScreenPos(timelineP0);
ImGui.InvisibleButton("timeline_timetracker_canvas", timelineSize with { Y = _timeBarHeight }, ImGuiButtonFlags.MouseButtonLeft); ImGui.InvisibleButton("timeline_timetracker_canvas", timelineSize with { Y = timeBarHeight }, ImGuiButtonFlags.MouseButtonLeft);
IsActive = ImGui.IsItemActive(); IsActive = ImGui.IsItemActive();
if (IsActive && ImGui.IsMouseDragging(ImGuiMouseButton.Left)) if (IsActive && ImGui.IsMouseDragging(ImGuiMouseButton.Left))
{ {
@@ -127,15 +128,15 @@ public class TimeTracker : IDisposable
} }
{ // draw time + time grid { // draw time + time grid
for (float x = 0; x < timelineSize.X; x += _timeStep.X) for (float x = 0; x < timelineSize.X; x += timeStep.X)
{ {
var cursor = timelineP0.X + x; var cursor = timelineP0.X + x;
drawList.AddLine(new Vector2(cursor, timelineP0.Y + _timeHeight + 2.5f), new Vector2(cursor, timelineP0.Y + _timeBarHeight), 0xA0FFFFFF); drawList.AddLine(new Vector2(cursor, timelineP0.Y + timeHeight + 2.5f), new Vector2(cursor, timelineP0.Y + timeBarHeight), 0xA0FFFFFF);
drawList.AddLine(new Vector2(cursor, timelineP0.Y + _timeBarHeight), timelineP1 with { X = cursor }, 0x28C8C8C8); drawList.AddLine(new Vector2(cursor, timelineP0.Y + timeBarHeight), timelineP1 with { X = cursor }, 0x28C8C8C8);
drawList.AddText(fontPtr, 14, new Vector2(cursor + 4, timelineP0.Y + 7.5f), 0x50FFFFFF, $"{x / timeRatio.X:F1}s"); drawList.AddText(fontPtr, 14 * dpiScale, new Vector2(cursor + 4, timelineP0.Y + 7.5f), 0x50FFFFFF, $"{x / timeRatio.X:F1}s");
} }
for (float y = _timeBarHeight; y < timelineSize.Y; y += _timeStep.Y) for (float y = timeBarHeight; y < timelineSize.Y; y += timeStep.Y)
{ {
drawList.AddLine(timelineP0 with { Y = timelineP0.Y + y }, timelineP1 with { Y = timelineP0.Y + y }, 0x28C8C8C8); drawList.AddLine(timelineP0 with { Y = timelineP0.Y + y }, timelineP1 with { Y = timelineP0.Y + y }, 0x28C8C8C8);
} }
@@ -144,28 +145,28 @@ public class TimeTracker : IDisposable
ImGui.PushStyleVar(ImGuiStyleVar.SelectableTextAlign, new Vector2(0.0f, 0.5f)); ImGui.PushStyleVar(ImGuiStyleVar.SelectableTextAlign, new Vector2(0.0f, 0.5f));
for (int i = 0; i < animations.Count; i++) for (int i = 0; i < animations.Count; i++)
{ {
var y = timelineP0.Y + _timeBarHeight + _timeStep.Y * i; var y = timelineP0.Y + timeBarHeight + timeStep.Y * i;
animations[i].ImGuiAnimation(s, saver, drawList, fontPtr, timelineP0, treeP0, _timeStep, timeRatio, y, _thickness, i); animations[i].ImGuiAnimation(s, saver, drawList, fontPtr, timelineP0, treeP0, timeStep, timeRatio, y, thickness, i);
DrawSeparator(drawList, timelineP0, y + _timeStep.Y, animations[i].EndTime * timeRatio.X, ETrackerType.End); DrawSeparator(drawList, timelineP0, y + timeStep.Y, animations[i].EndTime * timeRatio.X, timeHeight, timeBarHeight, ETrackerType.End);
} }
ImGui.PopStyleVar(); ImGui.PopStyleVar();
for (int i = 0; i < animations.Count; i++) for (int i = 0; i < animations.Count; i++)
{ {
var y = timelineP0.Y + _timeBarHeight + _timeStep.Y * i; var y = timelineP0.Y + timeBarHeight + timeStep.Y * i;
for (int j = 0; j < animations[i].Sequences.Length - 1; j++) for (int j = 0; j < animations[i].Sequences.Length - 1; j++)
{ {
DrawSeparator(drawList, timelineP0, y + _timeStep.Y - _thickness, animations[i].Sequences[j].EndTime * timeRatio.X - 0.5f, ETrackerType.InBetween); DrawSeparator(drawList, timelineP0, y + timeStep.Y - thickness, animations[i].Sequences[j].EndTime * timeRatio.X - 0.5f, timeHeight, timeBarHeight, ETrackerType.InBetween);
} }
} }
DrawSeparator(drawList, timelineP0, timelineP1.Y, ElapsedTime * timeRatio.X, ETrackerType.Frame); DrawSeparator(drawList, timelineP0, timelineP1.Y, ElapsedTime * timeRatio.X, timeHeight, timeBarHeight, ETrackerType.Frame);
drawList.PopClipRect(); drawList.PopClipRect();
ImGui.EndChild(); ImGui.EndChild();
} }
private void DrawSeparator(ImDrawListPtr drawList, Vector2 origin, float y, float time, ETrackerType separatorType) private void DrawSeparator(ImDrawListPtr drawList, Vector2 origin, float y, float time, float timeHeight, float timeBarHeight, ETrackerType separatorType)
{ {
float size = separatorType switch float size = separatorType switch
{ {
@@ -177,7 +178,7 @@ public class TimeTracker : IDisposable
Vector2 p1 = separatorType switch Vector2 p1 = separatorType switch
{ {
ETrackerType.Frame => new Vector2(origin.X + time, origin.Y + _timeBarHeight), ETrackerType.Frame => new Vector2(origin.X + time, origin.Y + timeBarHeight),
ETrackerType.End => origin with { X = origin.X + time }, ETrackerType.End => origin with { X = origin.X + time },
ETrackerType.InBetween => origin with { X = origin.X + time }, ETrackerType.InBetween => origin with { X = origin.X + time },
_ => throw new ArgumentOutOfRangeException(nameof(separatorType), separatorType, null) _ => throw new ArgumentOutOfRangeException(nameof(separatorType), separatorType, null)
@@ -198,7 +199,7 @@ public class TimeTracker : IDisposable
color = 0xFF30478C; color = 0xFF30478C;
var xl = p1.X - size; var xl = p1.X - size;
var xr = p1.X + size; var xr = p1.X + size;
var yb = origin.Y + _timeBarHeight - _timeHeight / 2.0f; var yb = origin.Y + timeBarHeight - timeHeight / 2.0f;
drawList.AddLine(p1, p2, color, 1f); drawList.AddLine(p1, p2, color, 1f);
drawList.AddQuadFilled(origin with { X = xl }, origin with { X = xr }, new Vector2(xr, yb), new Vector2(xl, yb), color); drawList.AddQuadFilled(origin with { X = xl }, origin with { X = xr }, new Vector2(xr, yb), new Vector2(xl, yb), color);
@@ -209,7 +210,7 @@ public class TimeTracker : IDisposable
drawList.AddTriangleFilled(p1, p1 with { X = p1.X - size }, p1 with { Y = p1.Y + size }, color); drawList.AddTriangleFilled(p1, p1 with { X = p1.X - size }, p1 with { Y = p1.Y + size }, color);
break; break;
case ETrackerType.InBetween: case ETrackerType.InBetween:
p1.Y += _timeBarHeight; p1.Y += timeBarHeight;
drawList.AddLine(p1, p2, color, 1f); drawList.AddLine(p1, p2, color, 1f);
drawList.AddTriangleFilled(p1, new Vector2(p1.X - size / 2.0f, p1.Y - size), new Vector2(p1.X + size / 2.0f, p1.Y - size), color); drawList.AddTriangleFilled(p1, new Vector2(p1.X - size / 2.0f, p1.Y - size), new Vector2(p1.X + size / 2.0f, p1.Y - size), color);
break; break;

View File

@@ -63,6 +63,7 @@ public class SnimGui
private readonly Save _saver = new (); private readonly Save _saver = new ();
private readonly string _renderer; private readonly string _renderer;
private readonly string _version; private readonly string _version;
private readonly float _tableWidth;
private Vector2 _outlinerSize; private Vector2 _outlinerSize;
private bool _ti_open; private bool _ti_open;
@@ -73,13 +74,15 @@ public class SnimGui
private readonly Vector4 _errorColor = new (0.761f, 0.169f, 0.169f, 1.0f); private readonly Vector4 _errorColor = new (0.761f, 0.169f, 0.169f, 1.0f);
private const uint _dockspaceId = 1337; private const uint _dockspaceId = 1337;
private const float _tableWidth = 17;
public SnimGui(int width, int height) public SnimGui(int width, int height)
{ {
Controller = new ImGuiController(width, height);
_renderer = GL.GetString(StringName.Renderer); _renderer = GL.GetString(StringName.Renderer);
_version = "OpenGL " + GL.GetString(StringName.Version); _version = "OpenGL " + GL.GetString(StringName.Version);
Controller = new ImGuiController(width, height); _tableWidth = 17 * Controller.DpiScale;
Theme(); Theme();
} }