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);
var io = ImGui.GetIO();
FontNormal = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeui.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);
FontNormal = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeui.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);
io.BackendFlags |= ImGuiBackendFlags.RendererHasVtxOffset;
io.ConfigFlags |= ImGuiConfigFlags.NavEnableKeyboard;

View File

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

View File

@ -108,6 +108,24 @@ public class Animation : IDisposable
{
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(() =>
{
s.Renderer.Options.SelectAnimation(i);
@ -138,17 +156,5 @@ public class Animation : IDisposable
ImGui.Separator();
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);
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();
}

View File

@ -55,66 +55,67 @@ public class TimeTracker : IDisposable
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" };
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 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 });
var timelineP1 = new Vector2(treeP0.X + canvasSize.X, treeP0.Y + canvasMaxY);
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 timeRatio = timelineSize / MaxElapsedTime;
var drawList = ImGui.GetWindowDrawList();
drawList.PushClipRect(treeP0, timelineP1, true);
drawList.AddRectFilled(treeP0, treeP1, 0xFF1F1C1C);
drawList.AddRectFilled(timelineP0, timelineP1 with { Y = timelineP0.Y + _timeBarHeight }, 0xFF141414);
drawList.AddRectFilled(timelineP0 with { Y = timelineP0.Y + _timeBarHeight }, timelineP1, 0xFF242424);
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.AddRectFilled(timelineP0, timelineP1 with { Y = timelineP0.Y + timeBarHeight }, 0xFF141414);
drawList.AddRectFilled(timelineP0 with { Y = timelineP0.Y + timeBarHeight }, timelineP1, 0xFF242424);
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);
// adding margin
treeP0.X += _margin;
treeP1.X -= _margin;
var margin = 5.0f * dpiScale;
treeP0.X += margin;
treeP1.X -= margin;
// control buttons
for (int i = 0; i < _icons.Length; i++)
{
var x = _buttonSize.X * 2.0f * i;
ImGui.SetCursorScreenPos(treeP0 with { X = treeP1.X - x - _buttonSize.X * 2.0f + _thickness });
if (ImGui.ImageButton($"timeline_actions_{_icons[i]}", icons[i == 1 ? IsPaused ? "tl_play" : "tl_pause" : _icons[i]].GetPointer(), _buttonSize))
var x = buttonWidth * 2.0f * i;
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(), new Vector2(buttonWidth)))
{
switch (i)
{
case 0:
SafeSetElapsedTime(ElapsedTime + _timeStep.X / timeRatio.X);
SafeSetElapsedTime(ElapsedTime + timeStep.X / timeRatio.X);
break;
case 1:
IsPaused = !IsPaused;
break;
case 2:
SafeSetElapsedTime(ElapsedTime - _timeStep.X / timeRatio.X);
SafeSetElapsedTime(ElapsedTime - timeStep.X / timeRatio.X);
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.InvisibleButton("timeline_timetracker_canvas", timelineSize with { Y = _timeBarHeight }, ImGuiButtonFlags.MouseButtonLeft);
ImGui.InvisibleButton("timeline_timetracker_canvas", timelineSize with { Y = timeBarHeight }, ImGuiButtonFlags.MouseButtonLeft);
IsActive = ImGui.IsItemActive();
if (IsActive && ImGui.IsMouseDragging(ImGuiMouseButton.Left))
{
@ -127,15 +128,15 @@ public class TimeTracker : IDisposable
}
{ // 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;
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.AddText(fontPtr, 14, new Vector2(cursor + 4, timelineP0.Y + 7.5f), 0x50FFFFFF, $"{x / timeRatio.X:F1}s");
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.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);
}
@ -144,28 +145,28 @@ public class TimeTracker : IDisposable
ImGui.PushStyleVar(ImGuiStyleVar.SelectableTextAlign, new Vector2(0.0f, 0.5f));
for (int i = 0; i < animations.Count; i++)
{
var y = timelineP0.Y + _timeBarHeight + _timeStep.Y * 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);
var y = timelineP0.Y + timeBarHeight + timeStep.Y * 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, timeHeight, timeBarHeight, ETrackerType.End);
}
ImGui.PopStyleVar();
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++)
{
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();
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
{
@ -177,7 +178,7 @@ public class TimeTracker : IDisposable
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.InBetween => origin with { X = origin.X + time },
_ => throw new ArgumentOutOfRangeException(nameof(separatorType), separatorType, null)
@ -198,7 +199,7 @@ public class TimeTracker : IDisposable
color = 0xFF30478C;
var xl = 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.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);
break;
case ETrackerType.InBetween:
p1.Y += _timeBarHeight;
p1.Y += timeBarHeight;
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);
break;

View File

@ -63,6 +63,7 @@ public class SnimGui
private readonly Save _saver = new ();
private readonly string _renderer;
private readonly string _version;
private readonly float _tableWidth;
private Vector2 _outlinerSize;
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 const uint _dockspaceId = 1337;
private const float _tableWidth = 17;
public SnimGui(int width, int height)
{
Controller = new ImGuiController(width, height);
_renderer = GL.GetString(StringName.Renderer);
_version = "OpenGL " + GL.GetString(StringName.Version);
Controller = new ImGuiController(width, height);
_tableWidth = 17 * Controller.DpiScale;
Theme();
}