using System; using System.Numerics; using Dalamud.Bindings.ImGui; using Dalamud.Interface; using Dalamud.Interface.Utility; using Dalamud.Interface.Utility.Raii; namespace Questionable.Windows; internal static class SidebarNav { public readonly record struct Item(FontAwesomeIcon Icon, string Label); public readonly record struct Group(string Label, Item[] Items); private const float RowMargin = 4f; private const float IconInset = 6f; private const float IconLabelGap = 22f; private const float RowRounding = 4f; public static int Draw(Group[] groups, int selected, float width = 168f) { int result = selected; using (ImRaii.Child("##qstSidebar", new Vector2(width * ImGuiHelpers.GlobalScale, 0f), border: false)) { using (ImRaii.PushId("QstSidebar")) { ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList(); float frameHeight = ImGui.GetFrameHeight(); float fontSize = ImGui.GetFontSize(); float globalScale = ImGuiHelpers.GlobalScale; float num = 4f * globalScale; int num2 = 0; bool flag = true; for (int i = 0; i < groups.Length; i++) { Group obj = groups[i]; ImGui.SetCursorPosY(ImGui.GetCursorPosY() + (flag ? 2f : 10f)); flag = false; ImGui.SetCursorPosX(ImGui.GetCursorPosX() + num); ImGui.TextColored(in UiThemeUtils.MutedTextColor, obj.Label.ToUpperInvariant()); Item[] items = obj.Items; for (int j = 0; j < items.Length; j++) { Item item = items[j]; bool flag2 = num2 == selected; ImGui.SetCursorPosX(ImGui.GetCursorPosX() + num); using (ImRaii.ColorDisposable colorDisposable = ImRaii.PushColor(ImGuiCol.Header, Vector4.Zero)) { colorDisposable.Push(ImGuiCol.HeaderHovered, Vector4.Zero); colorDisposable.Push(ImGuiCol.HeaderActive, Vector4.Zero); ImU8String label = new ImU8String(6, 1); label.AppendLiteral("##item"); label.AppendFormatted(num2); if (ImGui.Selectable(label, flag2, ImGuiSelectableFlags.None, new Vector2(ImGui.GetContentRegionAvail().X - num, frameHeight))) { result = num2; } } bool flag3 = ImGui.IsItemHovered(); Vector2 itemRectMin = ImGui.GetItemRectMin(); Vector2 itemRectMax = ImGui.GetItemRectMax(); float x = ImGui.GetStyle().ItemSpacing.X; float num3 = MathF.Truncate(x * 0.5f); itemRectMin.X += num3; itemRectMax.X -= x - num3; if (flag2) { windowDrawList.AddRectFilled(itemRectMin, itemRectMax, ImGui.ColorConvertFloat4ToU32(UiThemeUtils.AccentDimColor), 4f); } else if (flag3) { windowDrawList.AddRectFilled(itemRectMin, itemRectMax, ImGui.ColorConvertFloat4ToU32(UiThemeUtils.SubtleHoverColor), 4f); } uint col = ImGui.ColorConvertFloat4ToU32(flag2 ? UiThemeUtils.AccentColor : UiThemeUtils.DimTextColor); string text = item.Icon.ToIconString(); windowDrawList.AddText(UiBuilder.IconFont, fontSize, new Vector2(itemRectMin.X + 6f * globalScale, itemRectMin.Y + (frameHeight - fontSize) / 2f), col, text); Vector2 vector = ImGui.CalcTextSize(item.Label); windowDrawList.AddText(new Vector2(itemRectMin.X + 28f * globalScale, itemRectMin.Y + (frameHeight - vector.Y) / 2f), col, item.Label); if (flag2) { windowDrawList.AddRect(itemRectMin, itemRectMax, ImGui.ColorConvertFloat4ToU32(UiThemeUtils.CardBorderColor), 4f, ImDrawFlags.None, 1f); } num2++; } } Vector2 windowPos = ImGui.GetWindowPos(); Vector2 windowSize = ImGui.GetWindowSize(); windowDrawList.AddLine(new Vector2(windowPos.X + windowSize.X, windowPos.Y), new Vector2(windowPos.X + windowSize.X, windowPos.Y + windowSize.Y), ImGui.ColorConvertFloat4ToU32(UiThemeUtils.CardBorderColor), 1f); } } ImGui.SameLine(); return result; } }