forked from aly/qstbak
251 lines
11 KiB
C#
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)));
|
|
}
|
|
}
|