1
0
Fork 0
forked from aly/qstbak
qstbak/Questionable/Questionable.Windows.ChangelogComponents/ChangelogHeaderComponent.cs
2025-11-17 11:31:27 +10:00

251 lines
11 KiB
C#

using System;
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Utility.Raii;
namespace Questionable.Windows.ChangelogComponents;
internal sealed class ChangelogHeaderComponent
{
private float _animationTime;
public void Reset()
{
_animationTime = 0f;
}
public void Draw(Action<bool> onCloseClicked)
{
_animationTime += ImGui.GetIO().DeltaTime;
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
float x = ImGui.GetContentRegionAvail().X;
float headerHeight = 120f;
DrawBackground(windowDrawList, cursorScreenPos, x, headerHeight);
DrawAnimatedBorder(windowDrawList, cursorScreenPos, x, headerHeight);
DrawSparkles(windowDrawList, cursorScreenPos, x, headerHeight);
DrawCloseButton(windowDrawList, cursorScreenPos, x, onCloseClicked);
DrawHeaderContent(cursorScreenPos, x, headerHeight);
DrawAccentLine(windowDrawList, cursorScreenPos, x, headerHeight);
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 8f);
}
private void DrawBackground(ImDrawListPtr drawList, Vector2 headerStartPos, float contentWidth, float headerHeight)
{
float num = (MathF.Sin(_animationTime * 1.5f) + 1f) * 0.5f * 0.03f;
uint num2 = ImGui.ColorConvertFloat4ToU32(new Vector4(0.15f + num, 0.1f + num, 0.2f + num, 0.95f));
uint num3 = ImGui.ColorConvertFloat4ToU32(new Vector4(0.08f, 0.05f, 0.12f, 0.95f));
drawList.AddRectFilledMultiColor(headerStartPos, headerStartPos + new Vector2(contentWidth, headerHeight), num2, num2, num3, num3);
}
private void DrawAnimatedBorder(ImDrawListPtr drawList, Vector2 headerStartPos, float contentWidth, float headerHeight)
{
float num = 100f;
float num2 = 250f;
float num3 = _animationTime * num % num2;
float num4 = MathF.Ceiling(contentWidth / num2) + 2f;
for (int i = 0; (float)i < num4; i++)
{
float num5 = (float)i * num2 - num3;
float num6 = num5 + num2;
if (!(num6 < 0f) && !(num5 > contentWidth))
{
float num7 = MathF.Max(0f, num5);
float num8 = MathF.Min(contentWidth, num6);
float num9 = (num7 - num5) / num2;
float num10 = (num8 - num5) / num2;
float num11 = (MathF.Sin(num9 * (float)Math.PI * 2f - (float)Math.PI / 2f) + 1f) * 0.5f;
float num12 = (MathF.Sin(num10 * (float)Math.PI * 2f - (float)Math.PI / 2f) + 1f) * 0.5f;
Vector4 value = new Vector4(0.75f, 0.55f, 0.95f, num11 * 0.8f);
Vector4 value2 = new Vector4(0.55f, 0.75f, 0.95f, num11 * 0.8f);
Vector4 value3 = new Vector4(0.75f, 0.55f, 0.95f, num12 * 0.8f);
Vector4 value4 = new Vector4(0.55f, 0.75f, 0.95f, num12 * 0.8f);
float num13 = (num9 + num10) * 0.5f;
Vector4 input = Vector4.Lerp(value, value2, num13);
Vector4 input2 = Vector4.Lerp(value3, value4, num13 + 0.2f);
drawList.AddRectFilledMultiColor(headerStartPos + new Vector2(num7, 0f), headerStartPos + new Vector2(num8, 3f), ImGui.ColorConvertFloat4ToU32(input), ImGui.ColorConvertFloat4ToU32(input2), ImGui.ColorConvertFloat4ToU32(input2), ImGui.ColorConvertFloat4ToU32(input));
}
}
}
private void DrawSparkles(ImDrawListPtr drawList, Vector2 headerStartPos, float contentWidth, float headerHeight)
{
int num = 12;
for (int i = 0; i < num; i++)
{
float num2 = (float)i * 123.456f;
float num3 = 0.8f + (float)(i % 3) * 0.15f;
float num4 = _animationTime * num3;
float x = num2 * 12.345f % 1f * contentWidth;
float y = (MathF.Sin(num4 + num2) + 1f) * 0.5f * headerHeight;
Vector2 pos = headerStartPos + new Vector2(x, y);
float num5 = (MathF.Sin(num4 * 3f + num2 * 2f) + 1f) * 0.5f;
float alpha = num5 * 0.6f;
float size = 2f + num5 * 1.5f;
DrawSparkleShape(drawList, pos, size, alpha, i % 4, num4);
}
}
private static void DrawSparkleShape(ImDrawListPtr drawList, Vector2 pos, float size, float alpha, int type, float time)
{
switch (type)
{
case 0:
DrawCrossSparkle(drawList, pos, size, alpha);
break;
case 1:
DrawDiamondSparkle(drawList, pos, size, alpha);
break;
case 2:
DrawStarSparkle(drawList, pos, size, alpha, time);
break;
default:
DrawCircleSparkle(drawList, pos, size, alpha);
break;
}
}
private static void DrawCrossSparkle(ImDrawListPtr drawList, Vector2 pos, float size, float alpha)
{
float num = size * 0.8f;
float thickness = MathF.Max(1f, size * 0.3f);
drawList.AddLine(pos - new Vector2(num, 0f), pos + new Vector2(num, 0f), ImGui.ColorConvertFloat4ToU32(new Vector4(0.9f, 0.8f, 1f, alpha)), thickness);
drawList.AddLine(pos - new Vector2(0f, num), pos + new Vector2(0f, num), ImGui.ColorConvertFloat4ToU32(new Vector4(0.9f, 0.8f, 1f, alpha)), thickness);
drawList.AddCircleFilled(pos, size * 1.5f, ImGui.ColorConvertFloat4ToU32(new Vector4(0.75f, 0.55f, 0.95f, alpha * 0.2f)));
}
private static void DrawDiamondSparkle(ImDrawListPtr drawList, Vector2 pos, float size, float alpha)
{
float num = size * 0.7f;
Vector2 p = pos + new Vector2(0f, 0f - num);
Vector2 p2 = pos + new Vector2(num, 0f);
Vector2 p3 = pos + new Vector2(0f, num);
Vector2 p4 = pos + new Vector2(0f - num, 0f);
drawList.AddQuadFilled(p, p2, p3, p4, ImGui.ColorConvertFloat4ToU32(new Vector4(0.9f, 0.8f, 1f, alpha * 0.8f)));
drawList.AddCircleFilled(pos, size * 1.6f, ImGui.ColorConvertFloat4ToU32(new Vector4(0.75f, 0.55f, 0.95f, alpha * 0.25f)));
}
private static void DrawStarSparkle(ImDrawListPtr drawList, Vector2 pos, float size, float alpha, float time)
{
for (int i = 0; i < 4; i++)
{
float num = (float)i * (float)Math.PI * 0.5f;
float num2 = size * 0.3f;
float num3 = size * 0.9f;
float x = num - 0.3f;
float x2 = num + 0.3f;
Vector2 p = pos + new Vector2(MathF.Cos(x) * num2, MathF.Sin(x) * num2);
Vector2 p2 = pos + new Vector2(MathF.Cos(num) * num3, MathF.Sin(num) * num3);
Vector2 p3 = pos + new Vector2(MathF.Cos(x2) * num2, MathF.Sin(x2) * num2);
drawList.AddTriangleFilled(p, p2, p3, ImGui.ColorConvertFloat4ToU32(new Vector4(0.9f, 0.8f, 1f, alpha)));
}
drawList.AddCircleFilled(pos, size * 1.7f, ImGui.ColorConvertFloat4ToU32(new Vector4(0.75f, 0.55f, 0.95f, alpha * 0.3f)));
}
private static void DrawCircleSparkle(ImDrawListPtr drawList, Vector2 pos, float size, float alpha)
{
drawList.AddCircleFilled(pos, size, ImGui.ColorConvertFloat4ToU32(new Vector4(0.9f, 0.8f, 1f, alpha)));
drawList.AddCircleFilled(pos, size * 1.8f, ImGui.ColorConvertFloat4ToU32(new Vector4(0.75f, 0.55f, 0.95f, alpha * 0.3f)));
}
private void DrawCloseButton(ImDrawListPtr drawList, Vector2 headerStartPos, float contentWidth, Action<bool> onCloseClicked)
{
float num = 32f;
Vector2 vector = headerStartPos + new Vector2(contentWidth - num - 8f, 8f);
Vector2 center = vector + new Vector2(num * 0.5f, num * 0.5f);
Vector2 mousePos = ImGui.GetMousePos();
bool flag = mousePos.X >= vector.X && mousePos.X <= vector.X + num && mousePos.Y >= vector.Y && mousePos.Y <= vector.Y + num;
float w = (flag ? 0.9f : 0.5f);
float num2 = (flag ? ((MathF.Sin(_animationTime * 4f) + 1f) * 0.5f * 0.1f) : 0f);
uint col = (flag ? ImGui.ColorConvertFloat4ToU32(new Vector4(0.75f + num2, 0.55f, 0.95f, w)) : ImGui.ColorConvertFloat4ToU32(new Vector4(0.55f, 0.45f, 0.75f, w)));
drawList.AddCircleFilled(center, num * 0.4f, col);
DrawAnimatedCross(drawList, center, flag);
ImGui.SetCursorScreenPos(vector);
ImGui.InvisibleButton("CloseButton", new Vector2(num, num));
if (ImGui.IsItemClicked())
{
onCloseClicked(obj: false);
}
}
private void DrawAnimatedCross(ImDrawListPtr drawList, Vector2 center, bool isHovered)
{
float thickness = 2f;
float w = (isHovered ? 1f : 0.8f);
float x = (isHovered ? (MathF.Sin(_animationTime * 6f) * 0.1f) : 0f);
float num = MathF.Cos(x);
float num2 = MathF.Sin(x);
float num3 = 8f * 0.5f;
Vector2 vector = new Vector2((0f - num3) * num - (0f - num3) * num2, (0f - num3) * num2 + (0f - num3) * num);
Vector2 vector2 = new Vector2(num3 * num - num3 * num2, num3 * num2 + num3 * num);
Vector2 vector3 = new Vector2((0f - num3) * num - num3 * num2, (0f - num3) * num2 + num3 * num);
Vector2 vector4 = new Vector2(num3 * num - (0f - num3) * num2, num3 * num2 + (0f - num3) * num);
drawList.AddLine(center + vector, center + vector2, ImGui.ColorConvertFloat4ToU32(new Vector4(1f, 1f, 1f, w)), thickness);
drawList.AddLine(center + vector3, center + vector4, ImGui.ColorConvertFloat4ToU32(new Vector4(1f, 1f, 1f, w)), thickness);
}
private void DrawHeaderContent(Vector2 headerStartPos, float contentWidth, float headerHeight)
{
float fadeIn = MathF.Min(1f, _animationTime * 2f);
ImGui.SetCursorScreenPos(headerStartPos);
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 30f);
float centerX = contentWidth * 0.5f;
DrawIcon(centerX, fadeIn);
DrawTitle(centerX, fadeIn);
DrawSubtitle(centerX);
}
private void DrawIcon(float centerX, float fadeIn)
{
float num = MathF.Sin(_animationTime * 2f) * 3f;
float num2 = MathF.Sin(_animationTime * 1.5f + (float)Math.PI / 2f) * 1.5f;
using (ImRaii.PushFont(UiBuilder.IconFont))
{
string text = FontAwesomeIcon.FileAlt.ToIconString();
ImGui.SetCursorPosX(centerX - ImGui.CalcTextSize(text).X * 0.5f + num2);
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + num);
float w = (MathF.Sin(_animationTime * 3f) + 1f) * 0.5f * 0.3f;
Vector4 input = ((_animationTime * 0.5f % 1f < 0.5f) ? new Vector4(0.75f, 0.55f, 0.95f, w) : new Vector4(0.55f, 0.75f, 0.95f, w));
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
ImGui.GetWindowDrawList().AddText(UiBuilder.IconFont, ImGui.GetFontSize() * 1.2f, cursorScreenPos + new Vector2(2f, 2f), ImGui.ColorConvertFloat4ToU32(input), text);
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, fadeIn);
ImGui.TextColored(new Vector4(0.75f, 0.55f, 0.95f, 1f), text);
ImGui.PopStyleVar();
}
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - num + 4f);
}
private void DrawTitle(float centerX, float fadeIn)
{
float num = MathF.Max(0f, 1f - (_animationTime - 0.1f) * 3f);
float num2 = num * num * (3f - 2f * num) * 20f;
using (ImRaii.PushFont(UiBuilder.MonoFont))
{
string text = "What's New in Questionable?";
ImGui.SetCursorPosX(centerX - ImGui.CalcTextSize(text).X * 0.5f - num2);
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, fadeIn);
ImGui.TextColored(new Vector4(0.95f, 0.95f, 1f, 1f), text);
ImGui.PopStyleVar();
}
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 6f);
}
private void DrawSubtitle(float centerX)
{
float val = MathF.Max(0f, MathF.Min(1f, (_animationTime - 0.3f) * 2f));
string text = "Stay up to date with the latest features and improvements";
ImGui.SetCursorPosX(centerX - ImGui.CalcTextSize(text).X * 0.5f);
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, val);
ImGui.TextColored(new Vector4(0.7f, 0.7f, 0.8f, 0.9f), text);
ImGui.PopStyleVar();
}
private void DrawAccentLine(ImDrawListPtr drawList, Vector2 headerStartPos, float contentWidth, float headerHeight)
{
ImGui.SetCursorScreenPos(headerStartPos + new Vector2(0f, headerHeight));
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
float num = (MathF.Sin(_animationTime * 2f + (float)Math.PI) + 1f) * 0.5f;
drawList.AddRectFilledMultiColor(cursorScreenPos, cursorScreenPos + new Vector2(contentWidth, 2f), ImGui.ColorConvertFloat4ToU32(new Vector4(0.75f, 0.55f, 0.95f, 0.6f + num * 0.4f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.75f, 0.55f, 0.95f, 0.2f + num * 0.2f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.75f, 0.55f, 0.95f, 0.2f + num * 0.2f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.75f, 0.55f, 0.95f, 0.6f + num * 0.4f)));
}
}