forked from aly/qstbak
903 lines
31 KiB
C#
903 lines
31 KiB
C#
using System;
|
|
using System.Numerics;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Text;
|
|
using Dalamud.Bindings.ImGui;
|
|
using Dalamud.Game.Text;
|
|
using Dalamud.Interface;
|
|
using Dalamud.Interface.Colors;
|
|
using Dalamud.Interface.ManagedFontAtlas;
|
|
using Dalamud.Interface.Utility;
|
|
using Dalamud.Interface.Utility.Raii;
|
|
|
|
namespace Questionable.Windows;
|
|
|
|
internal static class UiThemeUtils
|
|
{
|
|
public readonly record struct GridCheckbox(string Label, bool Value, string? Tooltip = null);
|
|
|
|
public const float SpacingInner = 8f;
|
|
|
|
public const float SpacingSection = 16f;
|
|
|
|
public const float CardPadding = 12f;
|
|
|
|
public const float ControlWidth = 260f;
|
|
|
|
private static readonly uint AltRowColor = ImGui.ColorConvertFloat4ToU32(new Vector4(0.15f, 0.12f, 0.2f, 0.3f));
|
|
|
|
public static readonly Vector4 CardBackgroundColor = new Vector4(1f, 1f, 1f, 0.035f);
|
|
|
|
public static readonly Vector4 AccentColor = new Vector4(0.75f, 0.55f, 0.95f, 1f);
|
|
|
|
public static readonly Vector4 AccentDimColor;
|
|
|
|
public static readonly Vector4 CardBorderColor;
|
|
|
|
public static readonly Vector4 CardBorderHighColor;
|
|
|
|
private const float CardRounding = 6f;
|
|
|
|
public static readonly Vector4 PrimaryTextColor;
|
|
|
|
public static readonly Vector4 DimTextColor;
|
|
|
|
public static readonly Vector4 MutedTextColor;
|
|
|
|
public static readonly Vector4 PlayButtonColor;
|
|
|
|
public static readonly Vector4 PlayButtonHover;
|
|
|
|
public static readonly Vector4 PlayButtonActive;
|
|
|
|
public static readonly Vector4 PlayButtonText;
|
|
|
|
public static readonly Vector4 SubtleHoverColor;
|
|
|
|
public static readonly Vector4 SubtleActiveColor;
|
|
|
|
public static readonly Vector4 SubtlePressColor;
|
|
|
|
public static readonly Vector4 StatusComplete;
|
|
|
|
public static readonly Vector4 StatusActive;
|
|
|
|
public static readonly Vector4 StatusAvailable;
|
|
|
|
public static readonly Vector4 StatusAvailableComplete;
|
|
|
|
public static readonly Vector4 StatusLocked;
|
|
|
|
public static readonly Vector4 StatusUnobtainable;
|
|
|
|
public static readonly Vector4 StatusBlacklisted;
|
|
|
|
private static readonly string Ellipsis;
|
|
|
|
private static float _cardContentRightInset;
|
|
|
|
public const ImGuiTableFlags ThemedTableFlags = ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersInnerH;
|
|
|
|
public static void WrappedText(string text)
|
|
{
|
|
ImGui.PushTextWrapPos(ImGui.GetCursorPosX() + ImGui.GetContentRegionAvail().X);
|
|
ImGui.TextUnformatted(text);
|
|
ImGui.PopTextWrapPos();
|
|
}
|
|
|
|
public static void WrappedTextColored(Vector4 color, string text)
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.Text, color))
|
|
{
|
|
WrappedText(text);
|
|
}
|
|
}
|
|
|
|
public static string TruncateToWidth(string text, float maxWidth)
|
|
{
|
|
if (string.IsNullOrEmpty(text) || maxWidth <= 0f || ImGui.CalcTextSize(text).X <= maxWidth)
|
|
{
|
|
return text;
|
|
}
|
|
if (ImGui.CalcTextSize(Ellipsis).X > maxWidth)
|
|
{
|
|
return Ellipsis;
|
|
}
|
|
int num = 0;
|
|
int num2 = text.Length;
|
|
while (num < num2)
|
|
{
|
|
int num3 = (num + num2 + 1) / 2;
|
|
if (ImGui.CalcTextSize(string.Concat(text.AsSpan(0, num3), Ellipsis.AsSpan())).X <= maxWidth)
|
|
{
|
|
num = num3;
|
|
}
|
|
else
|
|
{
|
|
num2 = num3 - 1;
|
|
}
|
|
}
|
|
if (num > 0)
|
|
{
|
|
return string.Concat(text.AsSpan(0, num), Ellipsis.AsSpan());
|
|
}
|
|
return Ellipsis;
|
|
}
|
|
|
|
public static void RowLabel(string text, float reservedRightWidth)
|
|
{
|
|
float maxWidth = ImGui.GetContentRegionAvail().X - reservedRightWidth;
|
|
ImGui.TextUnformatted(TruncateToWidth(text, maxWidth));
|
|
}
|
|
|
|
public static void RowLabel(string text, float reservedRightWidth, Vector4 color)
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.Text, color))
|
|
{
|
|
RowLabel(text, reservedRightWidth);
|
|
}
|
|
}
|
|
|
|
public static (Vector2 ContentStartPos, float AvailableWidth, ImDrawListPtr DrawList) BeginCard()
|
|
{
|
|
Vector2 cursorPos = ImGui.GetCursorPos();
|
|
float x = ImGui.GetContentRegionAvail().X;
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
windowDrawList.ChannelsSplit(2);
|
|
windowDrawList.ChannelsSetCurrent(1);
|
|
ImGui.Indent(12f);
|
|
ImGui.SetCursorPosY(cursorPos.Y + 12f);
|
|
ImGui.PushItemWidth(-13f);
|
|
_cardContentRightInset = 12f;
|
|
return (ContentStartPos: cursorPos, AvailableWidth: x, DrawList: windowDrawList);
|
|
}
|
|
|
|
public static void EndCard(Vector2 contentStartPos, float availableWidth, ImDrawListPtr drawList)
|
|
{
|
|
ImGui.PopItemWidth();
|
|
ImGui.Unindent(12f);
|
|
_cardContentRightInset = 0f;
|
|
Vector2 cursorPos = ImGui.GetCursorPos();
|
|
drawList.ChannelsSetCurrent(0);
|
|
ImGui.SetCursorPos(contentStartPos);
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
ImGui.SetCursorPos(cursorPos + new Vector2(0f, 12f));
|
|
Vector2 cursorScreenPos2 = ImGui.GetCursorScreenPos();
|
|
drawList.AddRectFilled(cursorScreenPos, new Vector2(cursorScreenPos.X + availableWidth, cursorScreenPos2.Y), ImGui.ColorConvertFloat4ToU32(CardBackgroundColor), 6f);
|
|
drawList.AddRect(cursorScreenPos, new Vector2(cursorScreenPos.X + availableWidth, cursorScreenPos2.Y), ImGui.ColorConvertFloat4ToU32(CardBorderColor), 6f, ImDrawFlags.None, 1f);
|
|
drawList.ChannelsMerge();
|
|
ImGui.SetCursorPos(new Vector2(contentStartPos.X, cursorPos.Y + 12f));
|
|
}
|
|
|
|
public static ImRaii.TableDisposable BeginThemedTable(string id, int columns, ImGuiTableFlags extra = ImGuiTableFlags.None)
|
|
{
|
|
return ImRaii.Table(id, columns, ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersInnerH | extra);
|
|
}
|
|
|
|
public static void SectionHeader(string title)
|
|
{
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
float textLineHeight = ImGui.GetTextLineHeight();
|
|
windowDrawList.AddRectFilled(cursorScreenPos, new Vector2(cursorScreenPos.X + 3f, cursorScreenPos.Y + textLineHeight), ImGui.ColorConvertFloat4ToU32(AccentColor));
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + 3f + 6f);
|
|
ImGui.TextColored(in PrimaryTextColor, title);
|
|
}
|
|
|
|
public static void SectionSpacing()
|
|
{
|
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 16f);
|
|
}
|
|
|
|
public static void SubSectionHeader(string label)
|
|
{
|
|
ImGui.Spacing();
|
|
ImGui.TextColored(in DimTextColor, label);
|
|
}
|
|
|
|
public static void StatusBadge(string text, Vector4 color, FontAwesomeIcon icon)
|
|
{
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
float fontSize = ImGui.GetFontSize();
|
|
string text2 = icon.ToIconString();
|
|
Vector2 vector;
|
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
|
{
|
|
vector = ImGui.CalcTextSize(text2);
|
|
}
|
|
Vector2 vector2 = ImGui.CalcTextSize(text);
|
|
float num = 6f;
|
|
float num2 = 2f;
|
|
float num3 = 4f;
|
|
float x = num + vector.X + num3 + vector2.X + num;
|
|
float num4 = num2 + MathF.Max(vector.Y, vector2.Y) + num2;
|
|
Vector2 pMin = cursorScreenPos;
|
|
Vector2 pMax = cursorScreenPos + new Vector2(x, num4);
|
|
Vector4 input = new Vector4(color.X, color.Y, color.Z, 0.15f);
|
|
float rounding = num4 * 0.5f;
|
|
windowDrawList.AddRectFilled(pMin, pMax, ImGui.ColorConvertFloat4ToU32(input), rounding);
|
|
Vector2 pos = cursorScreenPos + new Vector2(num, num2);
|
|
windowDrawList.AddText(UiBuilder.IconFont, fontSize, pos, ImGui.ColorConvertFloat4ToU32(color), text2);
|
|
Vector2 pos2 = cursorScreenPos + new Vector2(num + vector.X + num3, num2);
|
|
windowDrawList.AddText(pos2, ImGui.ColorConvertFloat4ToU32(color), text);
|
|
ImGui.Dummy(new Vector2(x, num4));
|
|
}
|
|
|
|
public static void StatusBanner(string text, Vector4 color, FontAwesomeIcon icon)
|
|
{
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
float fontSize = ImGui.GetFontSize();
|
|
string text2 = icon.ToIconString();
|
|
float x = ImGui.GetContentRegionAvail().X;
|
|
Vector2 vector;
|
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
|
{
|
|
vector = ImGui.CalcTextSize(text2);
|
|
}
|
|
Vector2 vector2 = ImGui.CalcTextSize(text);
|
|
float y = 12f + MathF.Max(vector.Y, vector2.Y) + 12f;
|
|
float num = 6f;
|
|
Vector2 pMin = cursorScreenPos;
|
|
Vector2 pMax = cursorScreenPos + new Vector2(x, y);
|
|
Vector4 input = new Vector4(color.X, color.Y, color.Z, 0.1f);
|
|
Vector4 input2 = new Vector4(color.X, color.Y, color.Z, 0.25f);
|
|
windowDrawList.AddRectFilled(pMin, pMax, ImGui.ColorConvertFloat4ToU32(input), 6f);
|
|
windowDrawList.AddRect(pMin, pMax, ImGui.ColorConvertFloat4ToU32(input2), 6f, ImDrawFlags.None, 1f);
|
|
Vector2 pos = cursorScreenPos + new Vector2(12f, 12f);
|
|
windowDrawList.AddText(UiBuilder.IconFont, fontSize, pos, ImGui.ColorConvertFloat4ToU32(color), text2);
|
|
Vector2 pos2 = cursorScreenPos + new Vector2(12f + vector.X + num, 12f);
|
|
windowDrawList.AddText(pos2, ImGui.ColorConvertFloat4ToU32(color), text);
|
|
ImGui.Dummy(new Vector2(x, y));
|
|
}
|
|
|
|
public static void EmptyState(FontAwesomeIcon icon, string title, string? hint = null)
|
|
{
|
|
float x = ImGui.GetContentRegionAvail().X;
|
|
ImGui.Dummy(new Vector2(0f, 12f));
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
string text = icon.ToIconString();
|
|
float fontSize = ImGui.GetFontSize() * 1.4f;
|
|
Vector2 size;
|
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
|
{
|
|
size = ImGui.CalcTextSize(text) * 1.4f;
|
|
}
|
|
Vector2 pos = ImGui.GetCursorScreenPos() + new Vector2((x - size.X) / 2f, 0f);
|
|
windowDrawList.AddText(UiBuilder.IconFont, fontSize, pos, ImGui.ColorConvertFloat4ToU32(MutedTextColor), text);
|
|
ImGui.Dummy(size);
|
|
ImGui.Spacing();
|
|
ImGui.SetCursorPosX((x - ImGui.CalcTextSize(title).X) / 2f);
|
|
ImGui.TextColored(in DimTextColor, title);
|
|
if (hint != null)
|
|
{
|
|
ImGui.Spacing();
|
|
ImGui.SetCursorPosX((x - ImGui.CalcTextSize(hint).X) / 2f);
|
|
ImGui.TextColored(in MutedTextColor, hint);
|
|
}
|
|
ImGui.Dummy(new Vector2(0f, 12f));
|
|
}
|
|
|
|
public static void DrawTrackerCount(string formattedText, bool isComplete, bool isEmpty)
|
|
{
|
|
ImGui.PushFont(UiBuilder.MonoFont);
|
|
if (isEmpty)
|
|
{
|
|
ImGui.TextColored(in StatusUnobtainable, formattedText);
|
|
}
|
|
else if (isComplete)
|
|
{
|
|
ImGui.TextColored(in StatusComplete, formattedText);
|
|
}
|
|
else
|
|
{
|
|
ImGui.TextUnformatted(formattedText);
|
|
}
|
|
ImGui.PopFont();
|
|
}
|
|
|
|
public static void DrawTrackerGroupCaret(IFontHandle iconFontFixedWidth, bool expanded)
|
|
{
|
|
ImGui.TableSetBgColor(ImGuiTableBgTarget.RowBg0, ImGui.ColorConvertFloat4ToU32(CardBackgroundColor));
|
|
using (iconFontFixedWidth.Push())
|
|
{
|
|
ImGui.TextColored(in AccentColor, (expanded ? FontAwesomeIcon.CaretDown : FontAwesomeIcon.CaretRight).ToIconString());
|
|
}
|
|
}
|
|
|
|
public static void DrawAltRowBackground(int rowIndex)
|
|
{
|
|
if (rowIndex % 2 == 0)
|
|
{
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
windowDrawList.AddRectFilled(pMax: new Vector2(cursorScreenPos.X + ImGui.GetContentRegionAvail().X, cursorScreenPos.Y + ImGui.GetTextLineHeightWithSpacing()), pMin: cursorScreenPos, col: AltRowColor);
|
|
}
|
|
}
|
|
|
|
public static void DrawRowBackground(Vector2 topLeft, Vector2 bottomRight)
|
|
{
|
|
ImGui.GetWindowDrawList().AddRectFilled(topLeft, bottomRight, ImGui.ColorConvertFloat4ToU32(CardBackgroundColor), 3f);
|
|
}
|
|
|
|
public static bool ThemedAccordion(string id, string label, string? rightText, ref bool open, bool enabled = true)
|
|
{
|
|
using (ImRaii.PushId(id))
|
|
{
|
|
float x = ImGui.GetContentRegionAvail().X - _cardContentRightInset;
|
|
float frameHeight = ImGui.GetFrameHeight();
|
|
using (ImRaii.ColorDisposable colorDisposable = ImRaii.PushColor(ImGuiCol.Header, Vector4.Zero))
|
|
{
|
|
colorDisposable.Push(ImGuiCol.HeaderHovered, Vector4.Zero);
|
|
colorDisposable.Push(ImGuiCol.HeaderActive, Vector4.Zero);
|
|
if (ImGui.Selectable("##hdr", selected: false, ImGuiSelectableFlags.None, new Vector2(x, frameHeight)) && enabled)
|
|
{
|
|
open = !open;
|
|
}
|
|
}
|
|
bool num = enabled && ImGui.IsItemHovered();
|
|
Vector2 itemRectMin = ImGui.GetItemRectMin();
|
|
Vector2 itemRectMax = ImGui.GetItemRectMax();
|
|
float x2 = ImGui.GetStyle().ItemSpacing.X;
|
|
float num2 = MathF.Truncate(x2 * 0.5f);
|
|
itemRectMin.X += num2;
|
|
itemRectMax.X -= x2 - num2;
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
windowDrawList.AddRectFilled(itemRectMin, itemRectMax, ImGui.ColorConvertFloat4ToU32(CardBackgroundColor), 4f);
|
|
windowDrawList.AddRect(itemRectMin, itemRectMax, ImGui.ColorConvertFloat4ToU32(CardBorderColor), 4f, ImDrawFlags.None, 1f);
|
|
if (num)
|
|
{
|
|
windowDrawList.AddRectFilled(itemRectMin, itemRectMax, ImGui.ColorConvertFloat4ToU32(SubtleHoverColor), 4f);
|
|
}
|
|
float fontSize = ImGui.GetFontSize();
|
|
float num3 = itemRectMin.X + 12f;
|
|
if (enabled)
|
|
{
|
|
string text = (open ? FontAwesomeIcon.CaretDown : FontAwesomeIcon.CaretRight).ToIconString();
|
|
Vector2 vector;
|
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
|
{
|
|
vector = ImGui.CalcTextSize(text);
|
|
}
|
|
windowDrawList.AddText(UiBuilder.IconFont, fontSize, new Vector2(num3, itemRectMin.Y + (frameHeight - vector.Y) / 2f), ImGui.ColorConvertFloat4ToU32(AccentColor), text);
|
|
}
|
|
Vector2 vector2 = ImGui.CalcTextSize(label);
|
|
windowDrawList.AddText(new Vector2(num3 + 18f, itemRectMin.Y + (frameHeight - vector2.Y) / 2f), ImGui.ColorConvertFloat4ToU32(enabled ? PrimaryTextColor : DimTextColor), label);
|
|
if (!string.IsNullOrEmpty(rightText))
|
|
{
|
|
Vector2 vector3;
|
|
using (ImRaii.PushFont(UiBuilder.MonoFont))
|
|
{
|
|
vector3 = ImGui.CalcTextSize(rightText);
|
|
}
|
|
float x3 = itemRectMax.X - 12f - vector3.X;
|
|
windowDrawList.AddText(UiBuilder.MonoFont, fontSize, new Vector2(x3, itemRectMin.Y + (frameHeight - vector3.Y) / 2f), ImGui.ColorConvertFloat4ToU32(DimTextColor), rightText);
|
|
}
|
|
return open;
|
|
}
|
|
}
|
|
|
|
public static bool WrappedCheckbox(string label, ref bool value, string? infoTooltip = null)
|
|
{
|
|
ImU8String label2 = new ImU8String(2, 1);
|
|
label2.AppendLiteral("##");
|
|
label2.AppendFormatted(label);
|
|
bool result = ImGui.Checkbox(label2, ref value);
|
|
ImGui.SameLine();
|
|
if (infoTooltip != null)
|
|
{
|
|
float x;
|
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
|
{
|
|
x = ImGui.CalcTextSize(FontAwesomeIcon.InfoCircle.ToIconString()).X;
|
|
}
|
|
ImGui.PushTextWrapPos(ImGui.GetCursorPosX() + ImGui.GetContentRegionAvail().X - x - ImGui.GetStyle().ItemSpacing.X);
|
|
ImGui.Text(label);
|
|
ImGui.PopTextWrapPos();
|
|
ImGui.SameLine();
|
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
|
{
|
|
ImGui.TextColored(in DimTextColor, FontAwesomeIcon.InfoCircle.ToIconString());
|
|
}
|
|
if (ImGui.IsItemHovered())
|
|
{
|
|
using (ImRaii.Tooltip())
|
|
{
|
|
ImGui.PushTextWrapPos(400f);
|
|
ImGui.Text(infoTooltip);
|
|
ImGui.PopTextWrapPos();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ImGui.PushTextWrapPos(0f);
|
|
ImGui.Text(label);
|
|
ImGui.PopTextWrapPos();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static int CheckboxGrid(string id, ReadOnlySpan<GridCheckbox> items, int columns = 2)
|
|
{
|
|
using (ImRaii.PushId(id))
|
|
{
|
|
float x = ImGui.GetContentRegionAvail().X;
|
|
float x2 = ImGui.GetStyle().ItemSpacing.X;
|
|
float num = 0f;
|
|
ReadOnlySpan<GridCheckbox> readOnlySpan = items;
|
|
for (int i = 0; i < readOnlySpan.Length; i++)
|
|
{
|
|
GridCheckbox gridCheckbox = readOnlySpan[i];
|
|
float num2 = ImGui.GetFrameHeight() + x2 + ImGui.CalcTextSize(gridCheckbox.Label).X;
|
|
if (gridCheckbox.Tooltip != null)
|
|
{
|
|
num2 += x2 + ImGui.GetFontSize();
|
|
}
|
|
num = MathF.Max(num, num2);
|
|
}
|
|
while (columns > 1 && num > x / (float)columns)
|
|
{
|
|
columns--;
|
|
}
|
|
float num3 = x / (float)columns;
|
|
int result = -1;
|
|
for (int j = 0; j < items.Length; j++)
|
|
{
|
|
if (j % columns != 0)
|
|
{
|
|
ImGui.SameLine(num3 * (float)(j % columns));
|
|
}
|
|
bool v = items[j].Value;
|
|
ImU8String label = new ImU8String(4, 1);
|
|
label.AppendLiteral("##cg");
|
|
label.AppendFormatted(j);
|
|
if (ImGui.Checkbox(label, ref v))
|
|
{
|
|
result = j;
|
|
}
|
|
ImGui.SameLine();
|
|
ImGui.TextUnformatted(items[j].Label);
|
|
if (items[j].Tooltip != null)
|
|
{
|
|
ImGui.SameLine();
|
|
InfoIcon(items[j].Tooltip);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
public static bool SearchInput(string id, ref string text, float width = -1E-45f, string hint = "Search...")
|
|
{
|
|
ImGui.SetNextItemWidth(width);
|
|
return ImGui.InputTextWithHint(id, hint, ref text, 256);
|
|
}
|
|
|
|
public static void InfoIcon(string tooltip)
|
|
{
|
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
|
{
|
|
ImGui.TextColored(in DimTextColor, FontAwesomeIcon.InfoCircle.ToIconString());
|
|
}
|
|
if (ImGui.IsItemHovered())
|
|
{
|
|
using (ImRaii.Tooltip())
|
|
{
|
|
ImGui.PushTextWrapPos(400f);
|
|
ImGui.Text(tooltip);
|
|
ImGui.PopTextWrapPos();
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool AccentSliderInt(string label, ref int value, int min, int max, float width = 250f)
|
|
{
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
float frameHeight = ImGui.GetFrameHeight();
|
|
float num = ((max > min) ? ((float)(value - min) / (float)(max - min)) : 0f);
|
|
windowDrawList.AddRectFilled(cursorScreenPos, new Vector2(cursorScreenPos.X + width * num, cursorScreenPos.Y + frameHeight), ImGui.ColorConvertFloat4ToU32(AccentDimColor), 4f);
|
|
using (ImRaii.PushColor(ImGuiCol.FrameBg, new Vector4(0.15f, 0.12f, 0.2f, 0.5f)))
|
|
{
|
|
ImGui.SetNextItemWidth(width);
|
|
return ImGui.SliderInt(label, ref value, min, max);
|
|
}
|
|
}
|
|
|
|
public static bool AccentSliderFloat(string label, ref float value, float min, float max, string format = "%.1f", float width = 250f)
|
|
{
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
float frameHeight = ImGui.GetFrameHeight();
|
|
float num = ((max > min) ? ((value - min) / (max - min)) : 0f);
|
|
windowDrawList.AddRectFilled(cursorScreenPos, new Vector2(cursorScreenPos.X + width * num, cursorScreenPos.Y + frameHeight), ImGui.ColorConvertFloat4ToU32(AccentDimColor), 4f);
|
|
using (ImRaii.PushColor(ImGuiCol.FrameBg, new Vector4(0.15f, 0.12f, 0.2f, 0.5f)))
|
|
{
|
|
ImGui.SetNextItemWidth(width);
|
|
return ImGui.SliderFloat(label, ref value, min, max, format);
|
|
}
|
|
}
|
|
|
|
public static bool ThemedCombo(string label, ref int currentItem, string[] items, int itemCount)
|
|
{
|
|
using ImRaii.ColorDisposable colorDisposable = ImRaii.PushColor(ImGuiCol.FrameBg, new Vector4(0.15f, 0.12f, 0.2f, 0.65f));
|
|
colorDisposable.Push(ImGuiCol.FrameBgHovered, new Vector4(0.2f, 0.16f, 0.28f, 0.75f));
|
|
colorDisposable.Push(ImGuiCol.FrameBgActive, new Vector4(0.22f, 0.18f, 0.3f, 0.85f));
|
|
string text = ((currentItem >= 0 && currentItem < itemCount) ? items[currentItem] : string.Empty);
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
float num = ImGui.CalcItemWidth();
|
|
float frameHeight = ImGui.GetFrameHeight();
|
|
bool result = false;
|
|
if (ImGui.BeginCombo(label, text, ImGuiComboFlags.NoArrowButton))
|
|
{
|
|
Vector4 accentColor = AccentColor;
|
|
accentColor.W = 0.35f;
|
|
using ImRaii.ColorDisposable colorDisposable2 = ImRaii.PushColor(ImGuiCol.Header, accentColor);
|
|
accentColor = AccentColor;
|
|
accentColor.W = 0.45f;
|
|
colorDisposable2.Push(ImGuiCol.HeaderHovered, accentColor);
|
|
accentColor = AccentColor;
|
|
accentColor.W = 0.6f;
|
|
colorDisposable2.Push(ImGuiCol.HeaderActive, accentColor);
|
|
colorDisposable2.Push(ImGuiCol.Text, new Vector4(0.95f, 0.95f, 1f, 1f));
|
|
for (int i = 0; i < itemCount; i++)
|
|
{
|
|
bool flag = i == currentItem;
|
|
if (ImGui.Selectable(items[i], flag))
|
|
{
|
|
currentItem = i;
|
|
result = true;
|
|
}
|
|
if (flag)
|
|
{
|
|
ImGui.SetItemDefaultFocus();
|
|
}
|
|
}
|
|
ImGui.EndCombo();
|
|
}
|
|
float x = ImGui.GetStyle().FramePadding.X;
|
|
float num2 = 5f;
|
|
float num3 = cursorScreenPos.X + num - x - num2;
|
|
float num4 = cursorScreenPos.Y + frameHeight * 0.5f;
|
|
windowDrawList.AddTriangleFilled(new Vector2(num3 - num2 * 0.5f, num4 - num2 * 0.4f), new Vector2(num3 + num2 * 0.5f, num4 - num2 * 0.4f), new Vector2(num3, num4 + num2 * 0.5f), ImGui.ColorConvertFloat4ToU32(DimTextColor));
|
|
return result;
|
|
}
|
|
|
|
public static bool SearchableCombo(string label, ref int currentItem, string[] items, ref string searchText, float width = 250f, string? previewOverride = null)
|
|
{
|
|
using ImRaii.ColorDisposable colorDisposable = ImRaii.PushColor(ImGuiCol.FrameBg, new Vector4(0.15f, 0.12f, 0.2f, 0.65f));
|
|
colorDisposable.Push(ImGuiCol.FrameBgHovered, new Vector4(0.2f, 0.16f, 0.28f, 0.75f));
|
|
colorDisposable.Push(ImGuiCol.FrameBgActive, new Vector4(0.22f, 0.18f, 0.3f, 0.85f));
|
|
string text = previewOverride ?? ((currentItem >= 0 && currentItem < items.Length) ? items[currentItem] : string.Empty);
|
|
ImGui.SetNextItemWidth(width);
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
float num = ImGui.CalcItemWidth();
|
|
float frameHeight = ImGui.GetFrameHeight();
|
|
bool result = false;
|
|
if (ImGui.BeginCombo(label, text, ImGuiComboFlags.NoArrowButton))
|
|
{
|
|
Vector4 accentColor = AccentColor;
|
|
accentColor.W = 0.35f;
|
|
using ImRaii.ColorDisposable colorDisposable2 = ImRaii.PushColor(ImGuiCol.Header, accentColor);
|
|
accentColor = AccentColor;
|
|
accentColor.W = 0.45f;
|
|
colorDisposable2.Push(ImGuiCol.HeaderHovered, accentColor);
|
|
accentColor = AccentColor;
|
|
accentColor.W = 0.6f;
|
|
colorDisposable2.Push(ImGuiCol.HeaderActive, accentColor);
|
|
colorDisposable2.Push(ImGuiCol.Text, new Vector4(0.95f, 0.95f, 1f, 1f));
|
|
if (ImGui.IsWindowAppearing())
|
|
{
|
|
searchText = string.Empty;
|
|
ImGui.SetKeyboardFocusHere();
|
|
}
|
|
ImGui.SetNextItemWidth(-1E-45f);
|
|
ImGui.InputTextWithHint("##search", "Search...", ref searchText, 256);
|
|
ImGui.Separator();
|
|
int num2 = items.Length;
|
|
if (!string.IsNullOrEmpty(searchText))
|
|
{
|
|
num2 = 0;
|
|
for (int i = 0; i < items.Length; i++)
|
|
{
|
|
if (items[i].Contains(searchText, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
num2++;
|
|
}
|
|
}
|
|
}
|
|
float textLineHeightWithSpacing = ImGui.GetTextLineHeightWithSpacing();
|
|
int max = Math.Max(1, (int)(250f * ImGuiHelpers.GlobalScale / textLineHeightWithSpacing));
|
|
float y = (float)Math.Clamp(Math.Max(num2, 1), 1, max) * textLineHeightWithSpacing + 4f;
|
|
using (ImRaii.Child("##items", new Vector2(0f, y)))
|
|
{
|
|
if (num2 == 0)
|
|
{
|
|
ImGui.TextColored(in MutedTextColor, "No matches");
|
|
}
|
|
else
|
|
{
|
|
for (int j = 0; j < items.Length; j++)
|
|
{
|
|
if (string.IsNullOrEmpty(searchText) || items[j].Contains(searchText, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
bool flag = j == currentItem;
|
|
if (ImGui.Selectable(items[j], flag))
|
|
{
|
|
currentItem = j;
|
|
result = true;
|
|
ImGui.CloseCurrentPopup();
|
|
}
|
|
if (flag)
|
|
{
|
|
ImGui.SetItemDefaultFocus();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ImGui.EndCombo();
|
|
}
|
|
float x = ImGui.GetStyle().FramePadding.X;
|
|
float num3 = 5f;
|
|
float num4 = cursorScreenPos.X + num - x - num3;
|
|
float num5 = cursorScreenPos.Y + frameHeight * 0.5f;
|
|
windowDrawList.AddTriangleFilled(new Vector2(num4 - num3 * 0.5f, num5 - num3 * 0.4f), new Vector2(num4 + num3 * 0.5f, num5 - num3 * 0.4f), new Vector2(num4, num5 + num3 * 0.5f), ImGui.ColorConvertFloat4ToU32(DimTextColor));
|
|
return result;
|
|
}
|
|
|
|
public static ImRaii.ColorDisposable PushProgressBarColors()
|
|
{
|
|
ImRaii.ColorDisposable colorDisposable = ImRaii.PushColor(ImGuiCol.PlotHistogram, AccentColor);
|
|
colorDisposable.Push(ImGuiCol.FrameBg, new Vector4(1f, 1f, 1f, 0.12f));
|
|
return colorDisposable;
|
|
}
|
|
|
|
public static void DrawTabUnderline()
|
|
{
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
Vector2 itemRectMin = ImGui.GetItemRectMin();
|
|
Vector2 itemRectMax = ImGui.GetItemRectMax();
|
|
windowDrawList.AddRectFilled(new Vector2(itemRectMin.X, itemRectMax.Y - 3f), new Vector2(itemRectMax.X, itemRectMax.Y), ImGui.ColorConvertFloat4ToU32(AccentColor));
|
|
}
|
|
|
|
public static int DrawTabBar(string label0, string label1, int selected)
|
|
{
|
|
InlineArray2<string> buffer = default(InlineArray2<string>);
|
|
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray2<string>, string>(ref buffer, 0) = label0;
|
|
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray2<string>, string>(ref buffer, 1) = label1;
|
|
return DrawTabBar(global::_003CPrivateImplementationDetails_003E.InlineArrayAsReadOnlySpan<InlineArray2<string>, string>(in buffer, 2), selected, equalWidth: true);
|
|
}
|
|
|
|
public static int DrawTabBar(ReadOnlySpan<string> labels, int selected, bool equalWidth = false)
|
|
{
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
float x = ImGui.GetContentRegionAvail().X;
|
|
float x2 = ImGui.GetStyle().ItemSpacing.X;
|
|
float x3 = ImGui.GetCursorScreenPos().X;
|
|
int result = selected;
|
|
float x4 = 0f;
|
|
float x5 = 0f;
|
|
float num = 0f;
|
|
float num2 = 0f;
|
|
float num3 = (equalWidth ? ((x - x2 * (float)(labels.Length - 1)) / (float)labels.Length) : 0f);
|
|
Span<float> span = stackalloc float[labels.Length];
|
|
int num4 = 0;
|
|
using (ImRaii.PushId("QstTabBar"))
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.Button, Vector4.Zero))
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.ButtonHovered, SubtleHoverColor))
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.ButtonActive, SubtleActiveColor))
|
|
{
|
|
float num5 = 0f;
|
|
for (int i = 0; i < labels.Length; i++)
|
|
{
|
|
float num6 = (equalWidth ? num3 : (ImGui.CalcTextSize(labels[i]).X + ImGui.GetStyle().FramePadding.X * 2f));
|
|
if (i > 0)
|
|
{
|
|
if (num5 + x2 + num6 <= x)
|
|
{
|
|
ImGui.SameLine();
|
|
num5 += x2;
|
|
}
|
|
else
|
|
{
|
|
span[num4++] = num2;
|
|
num5 = 0f;
|
|
}
|
|
}
|
|
using (ImRaii.PushColor(ImGuiCol.Text, (i == selected) ? AccentColor : DimTextColor))
|
|
{
|
|
if (ImGui.Button(labels[i], new Vector2(num6, 0f)))
|
|
{
|
|
result = i;
|
|
}
|
|
}
|
|
if (i == selected)
|
|
{
|
|
x4 = ImGui.GetItemRectMin().X;
|
|
x5 = ImGui.GetItemRectMax().X;
|
|
num = ImGui.GetItemRectMax().Y;
|
|
}
|
|
num2 = ImGui.GetItemRectMax().Y;
|
|
num5 += num6;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
span[num4++] = num2;
|
|
for (int j = 0; j < num4; j++)
|
|
{
|
|
windowDrawList.AddRectFilled(new Vector2(x3, span[j]), new Vector2(x3 + x, span[j] + 2f), ImGui.ColorConvertFloat4ToU32(AccentDimColor));
|
|
}
|
|
windowDrawList.AddRectFilled(new Vector2(x4, num), new Vector2(x5, num + 2f), ImGui.ColorConvertFloat4ToU32(AccentColor));
|
|
ImGui.Spacing();
|
|
return result;
|
|
}
|
|
|
|
public static bool IconButton(FontAwesomeIcon icon, float size)
|
|
{
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
ImU8String label = new ImU8String(2, 1);
|
|
label.AppendLiteral("##");
|
|
label.AppendFormatted(icon);
|
|
bool result = ImGui.Button(label, new Vector2(size, size));
|
|
string text = icon.ToIconString();
|
|
Vector2 vector;
|
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
|
{
|
|
vector = ImGui.CalcTextSize(text);
|
|
}
|
|
uint colorU = ImGui.GetColorU32(ImGuiCol.Text);
|
|
float x = cursorScreenPos.X + (size - vector.X) / 2f;
|
|
float y = cursorScreenPos.Y + (size - vector.Y) / 2f;
|
|
windowDrawList.AddText(UiBuilder.IconFont, ImGui.GetFontSize(), new Vector2(x, y), colorU, text);
|
|
return result;
|
|
}
|
|
|
|
public static bool IconTextButton(FontAwesomeIcon icon, string text)
|
|
{
|
|
string text2 = icon.ToIconString();
|
|
Vector2 vector;
|
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
|
{
|
|
vector = ImGui.CalcTextSize(text2);
|
|
}
|
|
Vector2 vector2 = ImGui.CalcTextSize(text);
|
|
float num = 6f;
|
|
float width = vector.X + num + vector2.X + 2f * ImGui.GetStyle().FramePadding.X;
|
|
return IconTextButton(icon, text, width);
|
|
}
|
|
|
|
public static bool IconTextButton(FontAwesomeIcon icon, string text, float width)
|
|
{
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
float frameHeight = ImGui.GetFrameHeight();
|
|
ImU8String label = new ImU8String(2, 1);
|
|
label.AppendLiteral("##");
|
|
label.AppendFormatted(text);
|
|
bool result = ImGui.Button(label, new Vector2(width, frameHeight));
|
|
string text2 = icon.ToIconString();
|
|
Vector2 vector;
|
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
|
{
|
|
vector = ImGui.CalcTextSize(text2);
|
|
}
|
|
Vector2 vector2 = ImGui.CalcTextSize(text);
|
|
float num = 6f;
|
|
float num2 = vector.X + num + vector2.X;
|
|
float num3 = cursorScreenPos.X + (width - num2) / 2f;
|
|
float y = cursorScreenPos.Y + ImGui.GetStyle().FramePadding.Y;
|
|
uint colorU = ImGui.GetColorU32(ImGuiCol.Text);
|
|
windowDrawList.AddText(UiBuilder.IconFont, ImGui.GetFontSize(), new Vector2(num3, y), colorU, text2);
|
|
windowDrawList.AddText(new Vector2(num3 + vector.X + num, y), colorU, text);
|
|
return result;
|
|
}
|
|
|
|
public static bool PillButton(string label, bool selected)
|
|
{
|
|
float value = ImGui.GetFrameHeight() * 0.5f;
|
|
Vector2 framePadding = ImGui.GetStyle().FramePadding;
|
|
using (ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, value))
|
|
{
|
|
using (ImRaii.PushStyle(ImGuiStyleVar.FramePadding, new Vector2(framePadding.X * 2f, framePadding.Y)))
|
|
{
|
|
using (ImRaii.PushStyle(ImGuiStyleVar.FrameBorderSize, selected ? 1f : 0f))
|
|
{
|
|
using ImRaii.ColorDisposable colorDisposable = new ImRaii.ColorDisposable();
|
|
if (selected)
|
|
{
|
|
colorDisposable.Push(ImGuiCol.Button, new Vector4(0.55f, 0.35f, 0.8f, 0.3f));
|
|
colorDisposable.Push(ImGuiCol.ButtonHovered, new Vector4(0.55f, 0.35f, 0.8f, 0.4f));
|
|
colorDisposable.Push(ImGuiCol.ButtonActive, new Vector4(0.55f, 0.35f, 0.8f, 0.5f));
|
|
colorDisposable.Push(ImGuiCol.Border, CardBorderColor);
|
|
colorDisposable.Push(ImGuiCol.Text, AccentColor);
|
|
}
|
|
else
|
|
{
|
|
colorDisposable.Push(ImGuiCol.Button, Vector4.Zero);
|
|
colorDisposable.Push(ImGuiCol.ButtonHovered, SubtleHoverColor);
|
|
colorDisposable.Push(ImGuiCol.ButtonActive, SubtlePressColor);
|
|
colorDisposable.Push(ImGuiCol.Text, MutedTextColor);
|
|
}
|
|
return ImGui.Button(label);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool DestructiveButton(FontAwesomeIcon icon, string label)
|
|
{
|
|
bool result;
|
|
using (ImRaii.ColorDisposable colorDisposable = ImRaii.PushColor(ImGuiCol.Button, new Vector4(0.55f, 0.2f, 0.2f, 0.45f)))
|
|
{
|
|
colorDisposable.Push(ImGuiCol.ButtonHovered, new Vector4(0.7f, 0.25f, 0.25f, 0.65f));
|
|
using (ImRaii.Disabled(!ImGui.IsKeyDown(ImGuiKey.ModCtrl)))
|
|
{
|
|
result = IconTextButton(icon, label);
|
|
}
|
|
}
|
|
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
|
{
|
|
ImGui.SetTooltip("Hold CTRL to enable.");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static string CleanSeString(string text)
|
|
{
|
|
if (string.IsNullOrEmpty(text))
|
|
{
|
|
return text;
|
|
}
|
|
StringBuilder stringBuilder = new StringBuilder(text.Length);
|
|
foreach (char c in text)
|
|
{
|
|
if ((c < '\ue000' || c > '\uf8ff') && (c >= ' ' || c == '\n' || c == '\r' || c == '\t'))
|
|
{
|
|
stringBuilder.Append(c);
|
|
}
|
|
}
|
|
return stringBuilder.ToString().Trim();
|
|
}
|
|
|
|
static UiThemeUtils()
|
|
{
|
|
Vector4 accentColor = AccentColor;
|
|
accentColor.W = 0.12f;
|
|
AccentDimColor = accentColor;
|
|
accentColor = AccentColor;
|
|
accentColor.W = 0.16f;
|
|
CardBorderColor = accentColor;
|
|
accentColor = AccentColor;
|
|
accentColor.W = 0.35f;
|
|
CardBorderHighColor = accentColor;
|
|
PrimaryTextColor = new Vector4(0.95f, 0.95f, 1f, 1f);
|
|
DimTextColor = new Vector4(0.565f, 0.533f, 0.659f, 1f);
|
|
MutedTextColor = new Vector4(0.361f, 0.33f, 0.471f, 1f);
|
|
PlayButtonColor = new Vector4(0.75f, 0.55f, 0.95f, 1f);
|
|
PlayButtonHover = new Vector4(0.8f, 0.65f, 0.97f, 1f);
|
|
PlayButtonActive = new Vector4(0.85f, 0.7f, 1f, 1f);
|
|
PlayButtonText = new Vector4(0.08f, 0.06f, 0.12f, 1f);
|
|
SubtleHoverColor = new Vector4(1f, 1f, 1f, 0.04f);
|
|
SubtleActiveColor = new Vector4(1f, 1f, 1f, 0.06f);
|
|
SubtlePressColor = new Vector4(1f, 1f, 1f, 0.08f);
|
|
StatusComplete = ImGuiColors.ParsedGreen;
|
|
StatusActive = ImGuiColors.DalamudYellow;
|
|
StatusAvailable = ImGuiColors.DalamudYellow;
|
|
StatusAvailableComplete = ImGuiColors.ParsedBlue;
|
|
StatusLocked = ImGuiColors.DalamudRed;
|
|
StatusUnobtainable = ImGuiColors.DalamudGrey;
|
|
StatusBlacklisted = ImGuiColors.DalamudGrey3;
|
|
Ellipsis = ((SeIconChar)57434).ToIconString();
|
|
}
|
|
}
|