194 lines
6.1 KiB
C#
194 lines
6.1 KiB
C#
using System.Numerics;
|
|
using System.Text;
|
|
using Dalamud.Interface;
|
|
using Dalamud.Interface.Utility;
|
|
using ImGuiNET;
|
|
|
|
namespace ExtraChat.Util;
|
|
|
|
internal static class ImGuiUtil {
|
|
private static readonly Dictionary<int, string?[]> Tutorials = new() {
|
|
[0] = new[] {
|
|
"Create a linkshell",
|
|
|
|
"You can use this button to create a new linkshell.",
|
|
"Alternatively, you can be invited by a friend to join a linkshell.",
|
|
},
|
|
[1] = new[] {
|
|
"Refresh data",
|
|
|
|
"This button will refresh all data about your linkshells.",
|
|
"Generally, you shouldn't need to press this. Clicking on a linkshell refreshes the member list.",
|
|
},
|
|
[2] = new[] {
|
|
"Manage linkshells you're in",
|
|
|
|
"Clicking on a linkshell in this list will show you its members in the pane to the right.",
|
|
"You can also right-click the linkshell name to open a menu with various options.",
|
|
"If you were invited to a linkshell, you can accept the invitation in this menu.",
|
|
},
|
|
[3] = new[] {
|
|
"Talking in a linkshell",
|
|
|
|
"The number displayed before the linkshell name is the linkshell's number.",
|
|
"You can change this number by right-clicking.",
|
|
"This number is used to determine the command you should use to talk in the linkshell.",
|
|
"For example, linkshell 1 would use the command /ecl1, linkshell 2 would use /ecl2, etc.",
|
|
null,
|
|
"Click on this linkshell to see the member list.",
|
|
},
|
|
[4] = new[] {
|
|
"Members in a linkshell",
|
|
|
|
"Inside the member list, each member is shown with an optional symbol indicating their rank.",
|
|
null,
|
|
"Admins have this symbol: ★",
|
|
"Moderators have this symbol: ☆",
|
|
"Normal members have no symbol.",
|
|
"Invited members have this symbol: ?",
|
|
null,
|
|
"Members also appear dimmed when they are offline.",
|
|
},
|
|
[5] = new[] {
|
|
"Managing members in a linkshell",
|
|
|
|
"Moderators and admins of a linkshell can right-click on members in the member list to open a menu with various options.",
|
|
"Many options require holding the Control key to enable so that they aren't accidentally activated.",
|
|
},
|
|
};
|
|
|
|
internal static bool IconButton(FontAwesomeIcon icon, string? id = null, string? tooltip = null) {
|
|
var label = icon.ToIconString();
|
|
if (id != null) {
|
|
label += $"##{id}";
|
|
}
|
|
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
var ret = ImGui.Button(label);
|
|
ImGui.PopFont();
|
|
|
|
if (tooltip != null && ImGui.IsItemHovered()) {
|
|
ImGui.BeginTooltip();
|
|
ImGui.TextUnformatted(tooltip);
|
|
ImGui.EndTooltip();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
internal static bool SelectableConfirm(string label, ConfirmKey keys = ConfirmKey.Ctrl, string? tooltip = null) {
|
|
var selectable = ImGui.Selectable(label);
|
|
var hovered = ImGui.IsItemHovered();
|
|
|
|
var confirmHeld = true;
|
|
var mods = hovered ? new StringBuilder() : null;
|
|
foreach (var key in Enum.GetValues<ConfirmKey>()) {
|
|
if (!keys.HasFlag(key)) {
|
|
continue;
|
|
}
|
|
|
|
if (hovered) {
|
|
if (mods!.Length != 0) {
|
|
mods.Append('+');
|
|
}
|
|
|
|
mods.Append(key.ToString());
|
|
}
|
|
|
|
var held = key switch {
|
|
ConfirmKey.Ctrl => ImGui.GetIO().KeyCtrl,
|
|
ConfirmKey.Alt => ImGui.GetIO().KeyAlt,
|
|
ConfirmKey.Shift => ImGui.GetIO().KeyShift,
|
|
_ => false,
|
|
};
|
|
confirmHeld &= held;
|
|
}
|
|
|
|
if (!confirmHeld && hovered) {
|
|
ImGui.BeginTooltip();
|
|
var explainer = $"Hold {mods} to enable this option.";
|
|
var tip = tooltip == null ? explainer : $"{tooltip}\n{explainer}";
|
|
ImGui.TextUnformatted(tip);
|
|
ImGui.EndTooltip();
|
|
}
|
|
|
|
return selectable && confirmHeld;
|
|
}
|
|
|
|
internal static bool Tutorial(Plugin plugin, int step) {
|
|
var save = false;
|
|
ref var current = ref plugin.ConfigInfo.TutorialStep;
|
|
if (current < 0 || current != step) {
|
|
return save;
|
|
}
|
|
|
|
if (!Tutorials.TryGetValue(step, out var strings)) {
|
|
return save;
|
|
}
|
|
|
|
var max = Tutorials.Keys.Max();
|
|
|
|
const string popupId = "extrachat-tutorial";
|
|
ImGui.OpenPopup(popupId);
|
|
|
|
ImGui.GetForegroundDrawList().AddRect(
|
|
ImGui.GetItemRectMin() - new Vector2(2) * ImGuiHelpers.GlobalScale,
|
|
ImGui.GetItemRectMax() + new Vector2(2) * ImGuiHelpers.GlobalScale,
|
|
ImGui.GetColorU32(new Vector4(1, 0, 0, 1))
|
|
);
|
|
|
|
ImGui.SetNextWindowPos(ImGui.GetItemRectMax() + new Vector2(2) * ImGuiHelpers.GlobalScale);
|
|
ImGui.SetNextWindowSize(new Vector2(350, 0) * ImGuiHelpers.GlobalScale);
|
|
if (!ImGui.BeginPopup(popupId, ImGuiWindowFlags.AlwaysAutoResize)) {
|
|
return save;
|
|
}
|
|
|
|
ImGui.PushFont(UiBuilder.DefaultFont);
|
|
ImGui.PushTextWrapPos();
|
|
|
|
ImGui.TextUnformatted(strings[0]);
|
|
ImGui.Separator();
|
|
|
|
foreach (var body in strings[1..]) {
|
|
if (body == null) {
|
|
ImGui.Spacing();
|
|
continue;
|
|
}
|
|
|
|
ImGui.TextUnformatted(body);
|
|
}
|
|
|
|
if (step == max) {
|
|
if (ImGui.Button("Finish")) {
|
|
current = -1;
|
|
save = true;
|
|
}
|
|
} else {
|
|
if (ImGui.Button("Next")) {
|
|
current += 1;
|
|
save = true;
|
|
}
|
|
}
|
|
|
|
ImGui.SameLine();
|
|
|
|
if (ImGui.Button("Skip tutorial")) {
|
|
current = -1;
|
|
save = true;
|
|
}
|
|
|
|
ImGui.PopTextWrapPos();
|
|
ImGui.PopFont();
|
|
ImGui.EndPopup();
|
|
|
|
return save;
|
|
}
|
|
}
|
|
|
|
[Flags]
|
|
internal enum ConfirmKey {
|
|
Ctrl = 1 << 0,
|
|
Alt = 1 << 1,
|
|
Shift = 1 << 2,
|
|
}
|