208 lines
6.1 KiB
C#
208 lines
6.1 KiB
C#
using System.Text;
|
|
using Dalamud.Interface;
|
|
using EorzeaVotes.Utilities;
|
|
using ImGuiNET;
|
|
using Regexes = EorzeaVotes.Utilities.Regexes;
|
|
|
|
namespace EorzeaVotes.Ui;
|
|
|
|
internal static class ImGuiHelper {
|
|
internal static void Help(string text) {
|
|
ImGui.SameLine();
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
using (new OnDispose(ImGui.PopFont)) {
|
|
using var endColour = WithDisabledColour();
|
|
ImGui.TextUnformatted(FontAwesomeIcon.QuestionCircle.ToIconString());
|
|
}
|
|
|
|
Tooltip(text);
|
|
}
|
|
|
|
internal static OnDispose WithDisabledColour() {
|
|
var disabled = ImGui.GetStyle().Colors[(int) ImGuiCol.TextDisabled];
|
|
ImGui.PushStyleColor(ImGuiCol.Text, disabled);
|
|
return new OnDispose(ImGui.PopStyleColor);
|
|
}
|
|
|
|
internal static void Tooltip(string text) {
|
|
if (!ImGui.IsItemHovered()) {
|
|
return;
|
|
}
|
|
|
|
ImGui.BeginTooltip();
|
|
using var end = new OnDispose(ImGui.EndTooltip);
|
|
|
|
ImGui.PushTextWrapPos(ImGui.CalcTextSize("m").X * 30);
|
|
using var pop = new OnDispose(ImGui.PopTextWrapPos);
|
|
|
|
ImGui.TextUnformatted(text);
|
|
}
|
|
|
|
internal static bool EnumDropDownVertical<T>(string label, string? nullLabel, ref T? value, string? helpTooltip = null, Func<T?, string>? nameFunction = null)
|
|
where T : struct, Enum {
|
|
const string defaultNullLabel = "None";
|
|
|
|
ImGui.TextUnformatted(label);
|
|
if (helpTooltip != null) {
|
|
Help(helpTooltip);
|
|
}
|
|
|
|
ImGui.SetNextItemWidth(-1);
|
|
|
|
if (!ImGui.BeginCombo($"##{label}", GetName(value))) {
|
|
return false;
|
|
}
|
|
|
|
using var end = new OnDispose(ImGui.EndCombo);
|
|
|
|
var changed = false;
|
|
|
|
if (nullLabel != null && ImGui.Selectable(nullLabel, !value.HasValue)) {
|
|
value = null;
|
|
changed = true;
|
|
}
|
|
|
|
foreach (var variant in Enum.GetValues<T>()) {
|
|
if (ImGui.Selectable(GetName(variant), value.HasValue && value.Value.Equals(variant))) {
|
|
value = variant;
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
return changed;
|
|
|
|
string GetName(T? t) {
|
|
return nameFunction == null
|
|
? t == null
|
|
? nullLabel ?? defaultNullLabel
|
|
: Enum.GetName(t.Value) ?? "???"
|
|
: nameFunction(t);
|
|
}
|
|
}
|
|
|
|
internal static bool InputDateVertical(string label, ref string input, ref DateOnly? date) {
|
|
ImGui.TextUnformatted(label);
|
|
ImGui.SetNextItemWidth(-1);
|
|
if (!ImGui.InputText($"##{label}", ref input, 10)) {
|
|
return false;
|
|
}
|
|
|
|
var match = Regexes.DateRegex().Match(input);
|
|
if (!match.Success) {
|
|
date = null;
|
|
return true;
|
|
}
|
|
|
|
var success = true;
|
|
success &= ushort.TryParse(match.Groups[1].Value, out var year);
|
|
success &= byte.TryParse(match.Groups[2].Value, out var month);
|
|
success &= byte.TryParse(match.Groups[3].Value, out var day);
|
|
|
|
if (!success) {
|
|
date = null;
|
|
return true;
|
|
}
|
|
|
|
var now = DateOnly.FromDateTime(DateTime.UtcNow);
|
|
var valid = year >= now.Year - 115 && year <= now.Year;
|
|
|
|
// day and month will be caught be the ctor
|
|
if (!valid) {
|
|
date = null;
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
date = new DateOnly(year, month, day);
|
|
} catch {
|
|
date = null;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
internal static bool ComboCheckboxVertical(string label, ref bool value) {
|
|
ImGui.TextUnformatted(label);
|
|
ImGui.SetNextItemWidth(-1);
|
|
if (!ImGui.BeginCombo($"##{label}", value ? "Yes" : "No")) {
|
|
return false;
|
|
}
|
|
|
|
using var end = new OnDispose(ImGui.EndCombo);
|
|
|
|
var changed = false;
|
|
|
|
if (ImGui.Selectable("Yes", value)) {
|
|
changed = true;
|
|
value = true;
|
|
}
|
|
|
|
if (ImGui.Selectable("No", !value)) {
|
|
changed = true;
|
|
value = false;
|
|
}
|
|
|
|
return changed;
|
|
}
|
|
|
|
internal static OnDispose? WithDisabled(bool disabled) {
|
|
if (!disabled) {
|
|
return null;
|
|
}
|
|
|
|
ImGui.BeginDisabled();
|
|
return new OnDispose(ImGui.EndDisabled);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draw an input with the label above it instead of to the side.
|
|
/// </summary>
|
|
/// <param name="label">Label for the input</param>
|
|
/// <param name="drawInput">Function that draws an input and accepts an ID to be passed to the input label</param>
|
|
/// <param name="appendId">Optional string to be appended to the string passed to <see cref="drawInput"/></param>
|
|
/// <param name="helpTooltip">Optional string to be shown as a help tooltip next to the label</param>
|
|
/// <returns></returns>
|
|
internal static bool VerticalInput(string label, Func<string, bool> drawInput, string? appendId = null, string? helpTooltip = null) {
|
|
ImGui.TextUnformatted(label);
|
|
if (helpTooltip != null) {
|
|
Help(helpTooltip);
|
|
}
|
|
|
|
label = $"##{label}";
|
|
if (appendId != null) {
|
|
label += appendId;
|
|
}
|
|
|
|
ImGui.SetNextItemWidth(-1);
|
|
return drawInput(label);
|
|
}
|
|
|
|
internal static bool IconButton(FontAwesomeIcon icon, string? id = null) {
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
using var pop = new OnDispose(ImGui.PopFont);
|
|
|
|
var label = icon.ToIconString();
|
|
if (id != null) {
|
|
label += id;
|
|
}
|
|
|
|
return ImGui.Button(label);
|
|
}
|
|
|
|
internal static unsafe bool BeginTabItem(string label, bool forceOpen = false) {
|
|
var flags = forceOpen
|
|
? ImGuiTabItemFlags.SetSelected
|
|
: ImGuiTabItemFlags.None;
|
|
|
|
var bufSize = Encoding.UTF8.GetByteCount(label);
|
|
var labelBuf = stackalloc byte[bufSize + 1];
|
|
fixed (char* labelPtr = label) {
|
|
Encoding.UTF8.GetBytes(labelPtr, label.Length, labelBuf, bufSize);
|
|
}
|
|
|
|
labelBuf[bufSize] = 0;
|
|
|
|
return ImGuiNative.igBeginTabItem(labelBuf, null, flags) > 0u;
|
|
}
|
|
}
|