f37369cdda
Co-authored-by: Cursor <cursoragent@cursor.com>
1025 lines
32 KiB
C#
1025 lines
32 KiB
C#
using Dalamud.Game.ClientState.Objects.SubKinds;
|
|
using Dalamud.Interface;
|
|
using Dalamud.Interface.ImGuiFileDialog;
|
|
using Dalamud.Logging;
|
|
using HSUI.Config.Attributes;
|
|
using HSUI.Config.Tree;
|
|
using HSUI.Helpers;
|
|
using HSUI.Interface;
|
|
using Dalamud.Bindings.ImGui;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
|
|
|
|
namespace HSUI.Config.Profiles
|
|
{
|
|
public class ProfilesManager
|
|
{
|
|
#region Singleton
|
|
public readonly SectionNode ProfilesNode;
|
|
|
|
private ProfilesManager()
|
|
{
|
|
// fake nodes
|
|
ProfilesNode = new SectionNode();
|
|
ProfilesNode.Name = "Profiles";
|
|
|
|
NestedSubSectionNode subSectionNode = new NestedSubSectionNode();
|
|
subSectionNode.Name = "General";
|
|
subSectionNode.Depth = 0;
|
|
|
|
ProfilesConfigPageNode configPageNode = new ProfilesConfigPageNode();
|
|
|
|
subSectionNode.Add(configPageNode);
|
|
ProfilesNode.Add(subSectionNode);
|
|
|
|
ConfigurationManager.Instance.AddExtraSectionNode(ProfilesNode);
|
|
|
|
// default profile
|
|
if (!Profiles.ContainsKey(DefaultProfileName))
|
|
{
|
|
Profile defaultProfile = new Profile(DefaultProfileName);
|
|
Profiles.Add(DefaultProfileName, defaultProfile);
|
|
}
|
|
}
|
|
|
|
private bool ResetProfileToDefault(string profileName, bool forced = false)
|
|
{
|
|
string endPath = Path.Combine(ProfilesPath, profileName + ".HSUI");
|
|
|
|
if (forced)
|
|
{
|
|
try
|
|
{
|
|
File.Delete(endPath);
|
|
} catch { }
|
|
}
|
|
|
|
if (forced || !File.Exists(endPath))
|
|
{
|
|
try
|
|
{
|
|
Directory.CreateDirectory(ProfilesPath);
|
|
File.Copy(MediaDefaultProfilePath, endPath);
|
|
|
|
return true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Plugin.Logger.Error("Error copying default profile!: " + e.Message);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static void Initialize()
|
|
{
|
|
bool attemptRepair = false;
|
|
|
|
try
|
|
{
|
|
string jsonString = File.ReadAllText(JsonPath);
|
|
ProfilesManager? instance = JsonConvert.DeserializeObject<ProfilesManager>(jsonString);
|
|
if (instance != null)
|
|
{
|
|
Instance = instance;
|
|
|
|
bool needsSave = false;
|
|
foreach (Profile profile in Instance.Profiles.Values)
|
|
{
|
|
needsSave |= profile.AutoSwitchData.ValidateRolesData();
|
|
}
|
|
|
|
if (needsSave)
|
|
{
|
|
Instance.Save();
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
Instance = new ProfilesManager();
|
|
attemptRepair = true;
|
|
}
|
|
|
|
if (Instance == null)
|
|
{
|
|
Plugin.Logger.Error("Error initializing HSUI's profiles!!!");
|
|
return;
|
|
}
|
|
|
|
// attempt to reconstruct profile from files if the Profiles directory is missing
|
|
if (attemptRepair &&
|
|
!ConfigurationManager.Instance.IsFreshInstall() &&
|
|
!Directory.Exists(ProfilesPath))
|
|
{
|
|
Instance.CurrentProfileName = "Restored Profile";
|
|
|
|
Profile defaultProfile = new Profile(Instance.CurrentProfileName);
|
|
Instance.Profiles.Add(Instance.CurrentProfileName, defaultProfile);
|
|
}
|
|
|
|
// always make sure the default profile file is present
|
|
if (!File.Exists(DefaultProfilePath))
|
|
{
|
|
if (Instance.ResetProfileToDefault(DefaultProfileName))
|
|
{
|
|
if (Instance.CurrentProfileName == DefaultProfileName)
|
|
{
|
|
Instance.ReloadCurrentProfile();
|
|
}
|
|
}
|
|
}
|
|
|
|
Instance.UpdateSelectedIndex();
|
|
Instance.InitializeDefaultImportData();
|
|
}
|
|
|
|
private void InitializeDefaultImportData()
|
|
{
|
|
string importString = File.ReadAllText(MediaDefaultProfilePath);
|
|
|
|
string[] importStrings = importString.Trim().Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
|
|
if (importStrings.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
foreach (var str in importStrings)
|
|
{
|
|
try
|
|
{
|
|
ImportData importData = new ImportData(str);
|
|
_defaultImportData.Add(importData);
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
|
|
public static ProfilesManager Instance { get; private set; } = null!;
|
|
|
|
~ProfilesManager()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
protected void Dispose(bool disposing)
|
|
{
|
|
if (!disposing)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Instance = null!;
|
|
}
|
|
#endregion
|
|
|
|
private string _currentProfileName = "Default";
|
|
public string CurrentProfileName
|
|
{
|
|
get => _currentProfileName;
|
|
set
|
|
{
|
|
if (_currentProfileName == value)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_currentProfileName = value;
|
|
|
|
if (_currentProfileName == null || _currentProfileName.Length == 0)
|
|
{
|
|
_currentProfileName = DefaultProfileName;
|
|
}
|
|
|
|
UpdateSelectedIndex();
|
|
}
|
|
}
|
|
|
|
[JsonIgnore] private static string ProfilesPath => Path.Combine(ConfigurationManager.Instance.ConfigDirectory, "Profiles");
|
|
[JsonIgnore] private static string JsonPath => Path.Combine(ProfilesPath, "Profiles.json");
|
|
[JsonIgnore] private static string MediaDefaultProfilePath => Path.Combine(Plugin.AssemblyLocation, "Media", "Profiles", DefaultProfileName + ".HSUI");
|
|
|
|
[JsonIgnore] private static string DefaultProfileName = "Default";
|
|
[JsonIgnore] private static string DefaultProfilePath = Path.Combine(ProfilesPath, DefaultProfileName + ".HSUI");
|
|
|
|
[JsonIgnore] private List<ImportData> _defaultImportData = new List<ImportData>();
|
|
|
|
[JsonIgnore] private string _newProfileName = "";
|
|
[JsonIgnore] private int _copyFromIndex = 0;
|
|
[JsonIgnore] private int _selectedProfileIndex = 0;
|
|
[JsonIgnore] private string? _errorMessage = null;
|
|
[JsonIgnore] private string? _deletingProfileName = null;
|
|
[JsonIgnore] private string? _resetingProfileName = null;
|
|
[JsonIgnore] private string? _renamingProfileName = null;
|
|
|
|
[JsonIgnore] private FileDialogManager _fileDialogManager = new FileDialogManager();
|
|
|
|
public SortedList<string, Profile> Profiles = new SortedList<string, Profile>();
|
|
|
|
public ImportData? DefaultImportData(Type type)
|
|
{
|
|
return _defaultImportData.FirstOrDefault(o => o.ConfigType == type);
|
|
}
|
|
|
|
public Profile CurrentProfile()
|
|
{
|
|
if (_currentProfileName == null || _currentProfileName.Length == 0)
|
|
{
|
|
_currentProfileName = DefaultProfileName;
|
|
}
|
|
|
|
return Profiles[_currentProfileName];
|
|
}
|
|
|
|
public void SaveCurrentProfile()
|
|
{
|
|
if (ConfigurationManager.Instance == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
Save();
|
|
SaveCurrentProfile(ConfigurationManager.Instance.ExportCurrentConfigs());
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Plugin.Logger.Error("Error saving profile: " + e.Message);
|
|
}
|
|
}
|
|
|
|
public void SaveCurrentProfile(string? exportString)
|
|
{
|
|
if (exportString == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
Directory.CreateDirectory(ProfilesPath);
|
|
|
|
File.WriteAllText(CurrentProfilePath(), exportString);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Plugin.Logger.Error("Error saving profile: " + e.Message);
|
|
}
|
|
}
|
|
|
|
public bool LoadCurrentProfile(string oldProfile)
|
|
{
|
|
try
|
|
{
|
|
string importString = File.ReadAllText(CurrentProfilePath());
|
|
return ConfigurationManager.Instance.ImportProfile(oldProfile, _currentProfileName, importString);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Plugin.Logger.Error("Error loading profile: " + e.Message);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool ReloadCurrentProfile()
|
|
{
|
|
try
|
|
{
|
|
string importString = File.ReadAllText(CurrentProfilePath());
|
|
if (ConfigurationManager.Instance.ImportProfile(_currentProfileName, _currentProfileName, importString, true))
|
|
{
|
|
ConfigurationManager.Instance.SaveConfigurations(true);
|
|
return true;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Plugin.Logger.Error("Error re-loading profile: " + e.Message);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public void UpdateCurrentProfile()
|
|
{
|
|
IPlayerCharacter? player = Plugin.ObjectTable.LocalPlayer;
|
|
if (player == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
uint jobId = player.ClassJob.RowId;
|
|
Profile currentProfile = CurrentProfile();
|
|
JobRoles role = JobsHelper.RoleForJob(jobId);
|
|
int index = JobsHelper.JobsByRole[role].IndexOf(jobId);
|
|
|
|
if (index < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// current profile is enabled for this job, do nothing
|
|
if (currentProfile.AutoSwitchEnabled && currentProfile.AutoSwitchData.IsEnabled(role, index))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// find a profile that is enabled for this job
|
|
foreach (Profile profile in Profiles.Values)
|
|
{
|
|
if (!profile.AutoSwitchEnabled || profile == currentProfile)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// found a valid profile, switch to it
|
|
if (profile.AutoSwitchData.IsEnabled(role, index))
|
|
{
|
|
SwitchToProfile(profile.Name);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void CheckUpdateSwitchCurrentProfile(string specifiedProfile)
|
|
{
|
|
// found a valid profile, switch to it
|
|
if (Profiles.ContainsKey(specifiedProfile))
|
|
{
|
|
SwitchToProfile(specifiedProfile);
|
|
}
|
|
}
|
|
|
|
private unsafe string? SwitchToProfile(string profile, bool save = true)
|
|
{
|
|
// save if needed before switching
|
|
if (save)
|
|
{
|
|
ConfigurationManager.Instance.SaveConfigurations();
|
|
}
|
|
|
|
string oldProfile = _currentProfileName;
|
|
_currentProfileName = profile;
|
|
Profile currentProfile = CurrentProfile();
|
|
|
|
if (currentProfile.AttachHudEnabled && currentProfile.HudLayout != 0)
|
|
{
|
|
AddonConfig.Instance()->ChangeHudLayout((uint)currentProfile.HudLayout - 1);
|
|
}
|
|
|
|
if (!LoadCurrentProfile(oldProfile))
|
|
{
|
|
_currentProfileName = oldProfile;
|
|
return "Couldn't load profile \"" + profile + "\"!";
|
|
}
|
|
|
|
UpdateSelectedIndex();
|
|
|
|
try
|
|
{
|
|
Save();
|
|
FontsManager.Instance.BuildFonts();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Plugin.Logger.Error("Error saving profile: " + e.Message);
|
|
return "Couldn't load profile \"" + profile + "\"!";
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private void UpdateSelectedIndex()
|
|
{
|
|
_selectedProfileIndex = Math.Max(0, Profiles.IndexOfKey(_currentProfileName));
|
|
}
|
|
|
|
private string CurrentProfilePath()
|
|
{
|
|
return Path.Combine(ProfilesPath, _currentProfileName + ".HSUI");
|
|
}
|
|
|
|
private string? CloneProfile(string profileName, string newProfileName)
|
|
{
|
|
string srcPath = Path.Combine(ProfilesPath, profileName + ".HSUI");
|
|
string dstPath = Path.Combine(ProfilesPath, newProfileName + ".HSUI");
|
|
|
|
return CloneProfile(profileName, srcPath, newProfileName, dstPath);
|
|
}
|
|
|
|
private string? CloneProfile(string profileName, string srcPath, string newProfileName, string dstPath)
|
|
{
|
|
if (newProfileName.Length == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (Profiles.Keys.Contains(newProfileName))
|
|
{
|
|
return "A profile with the name \"" + newProfileName + "\" already exists!";
|
|
}
|
|
|
|
try
|
|
{
|
|
if (!File.Exists(srcPath))
|
|
{
|
|
return "Couldn't find profile \"" + profileName + "\"!";
|
|
}
|
|
|
|
if (File.Exists(dstPath))
|
|
{
|
|
return "A profile with the name \"" + newProfileName + "\" already exists!";
|
|
}
|
|
|
|
File.Copy(srcPath, dstPath);
|
|
Profile newProfile = new Profile(newProfileName);
|
|
Profiles.Add(newProfileName, newProfile);
|
|
|
|
Save();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Plugin.Logger.Error("Error cloning profile: " + e.Message);
|
|
return "Error trying to clone profile \"" + profileName + "\"!";
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private string? RenameCurrentProfile(string newProfileName)
|
|
{
|
|
if (_currentProfileName == newProfileName || newProfileName.Length == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (Profiles.ContainsKey(newProfileName))
|
|
{
|
|
return "A profile with the name \"" + newProfileName + "\" already exists!";
|
|
}
|
|
|
|
string srcPath = Path.Combine(ProfilesPath, _currentProfileName + ".HSUI");
|
|
string dstPath = Path.Combine(ProfilesPath, newProfileName + ".HSUI");
|
|
|
|
try
|
|
{
|
|
|
|
if (File.Exists(dstPath))
|
|
{
|
|
return "A profile with the name \"" + newProfileName + "\" already exists!";
|
|
}
|
|
|
|
File.Move(srcPath, dstPath);
|
|
|
|
Profile profile = Profiles[_currentProfileName];
|
|
profile.Name = newProfileName;
|
|
|
|
Profiles.Remove(_currentProfileName);
|
|
Profiles.Add(newProfileName, profile);
|
|
|
|
_currentProfileName = newProfileName;
|
|
|
|
Save();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Plugin.Logger.Error("Error renaming profile: " + e.Message);
|
|
return "Error trying to rename profile \"" + _currentProfileName + "\"!";
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private string? Import(string newProfileName, string importString)
|
|
{
|
|
if (newProfileName.Length == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (Profiles.Keys.Contains(newProfileName))
|
|
{
|
|
return "A profile with the name \"" + newProfileName + "\" already exists!";
|
|
}
|
|
|
|
string dstPath = Path.Combine(ProfilesPath, newProfileName + ".HSUI");
|
|
|
|
try
|
|
{
|
|
if (File.Exists(dstPath))
|
|
{
|
|
return "A profile with the name \"" + newProfileName + "\" already exists!";
|
|
}
|
|
|
|
File.WriteAllText(dstPath, importString);
|
|
|
|
Profile newProfile = new Profile(newProfileName);
|
|
Profiles.Add(newProfileName, newProfile);
|
|
|
|
string? errorMessage = SwitchToProfile(newProfileName, false);
|
|
|
|
if (errorMessage != null)
|
|
{
|
|
Profiles.Remove(newProfileName);
|
|
File.Delete(dstPath);
|
|
Save();
|
|
|
|
return errorMessage;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Plugin.Logger.Error("Error importing profile: " + e.Message);
|
|
return "Error trying to import profile \"" + newProfileName + "\"!";
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private string? ImportFromClipboard(string newProfileName)
|
|
{
|
|
string importString = ImGui.GetClipboardText();
|
|
if (importString.Length == 0)
|
|
{
|
|
return "Invalid import string!";
|
|
}
|
|
|
|
return Import(newProfileName, importString);
|
|
}
|
|
|
|
private void ImportFromFile(string newProfileName)
|
|
{
|
|
if (newProfileName.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Action<bool, string> callback = (finished, path) =>
|
|
{
|
|
try
|
|
{
|
|
if (finished && path.Length > 0)
|
|
{
|
|
string importString = File.ReadAllText(path);
|
|
_errorMessage = Import(newProfileName, importString);
|
|
|
|
if (_errorMessage == null)
|
|
{
|
|
_newProfileName = "";
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Plugin.Logger.Error("Error reading import file: " + e.Message);
|
|
_errorMessage = "Error reading the file!";
|
|
}
|
|
};
|
|
|
|
_fileDialogManager.OpenFileDialog("Select a HSUI Profile to import", "HSUI Profile{.HSUI}", callback);
|
|
}
|
|
|
|
private void ExportToFile(string newProfileName)
|
|
{
|
|
if (newProfileName.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Action<bool, string> callback = (finished, path) =>
|
|
{
|
|
try
|
|
{
|
|
string src = CurrentProfilePath();
|
|
if (finished && path.Length > 0 && src != path)
|
|
{
|
|
File.Copy(src, path, true);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Plugin.Logger.Error("Error copying file: " + e.Message);
|
|
_errorMessage = "Error exporting the file!";
|
|
}
|
|
};
|
|
|
|
_fileDialogManager.SaveFileDialog("Save Profile", "HSUI Profile{.HSUI}", newProfileName + ".HSUI", ".HSUI", callback);
|
|
}
|
|
|
|
private string? DeleteProfile(string profileName)
|
|
{
|
|
if (!Profiles.ContainsKey(profileName))
|
|
{
|
|
return "Couldn't find profile \"" + profileName + "\"!";
|
|
}
|
|
|
|
string path = Path.Combine(ProfilesPath, profileName + ".HSUI");
|
|
|
|
try
|
|
{
|
|
if (!File.Exists(path))
|
|
{
|
|
return "Couldn't find profile \"" + profileName + "\"!";
|
|
}
|
|
|
|
File.Delete(path);
|
|
Profiles.Remove(profileName);
|
|
|
|
Save();
|
|
|
|
ConfigurationManager.Instance.OnProfileDeleted(profileName);
|
|
|
|
if (_currentProfileName == profileName)
|
|
{
|
|
return SwitchToProfile(DefaultProfileName, false);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Plugin.Logger.Error("Error deleting profile: " + e.Message);
|
|
return "Error trying to delete profile \"" + profileName + "\"!";
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private void Save()
|
|
{
|
|
string jsonString = JsonConvert.SerializeObject(
|
|
this,
|
|
Formatting.Indented,
|
|
new JsonSerializerSettings
|
|
{
|
|
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
|
|
TypeNameHandling = TypeNameHandling.Objects
|
|
}
|
|
);
|
|
|
|
Directory.CreateDirectory(ProfilesPath);
|
|
File.WriteAllText(JsonPath, jsonString);
|
|
}
|
|
|
|
public bool Draw(ref bool changed)
|
|
{
|
|
string[] profiles = Profiles.Keys.ToArray();
|
|
|
|
if (ImGui.BeginChild("Profiles", new Vector2(800, 600), false))
|
|
{
|
|
if (Profiles.Count == 0)
|
|
{
|
|
ImGuiHelper.Tab();
|
|
ImGui.Text("Profiles not found in \"%appdata%/Roaming/XIVLauncher/pluginConfigs/HSUI/Profiles/\"");
|
|
return false;
|
|
}
|
|
|
|
ImGui.PushItemWidth(408);
|
|
ImGuiHelper.NewLineAndTab();
|
|
if (ImGui.Combo("Active Profile", ref _selectedProfileIndex, profiles, 10))
|
|
{
|
|
string newProfileName = profiles[_selectedProfileIndex];
|
|
|
|
if (_currentProfileName != newProfileName)
|
|
{
|
|
_errorMessage = SwitchToProfile(newProfileName);
|
|
}
|
|
}
|
|
|
|
// reset
|
|
ImGui.SameLine();
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
if (ImGui.Button("\uf2f9", new Vector2(0, 0)))
|
|
{
|
|
_resetingProfileName = _currentProfileName;
|
|
}
|
|
ImGui.PopFont();
|
|
ImGuiHelper.SetTooltip("Reset");
|
|
|
|
if (_currentProfileName != DefaultProfileName)
|
|
{
|
|
// rename
|
|
ImGui.SameLine();
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
if (ImGui.Button(FontAwesomeIcon.Pen.ToIconString()))
|
|
{
|
|
_renamingProfileName = _currentProfileName;
|
|
}
|
|
ImGui.PopFont();
|
|
ImGuiHelper.SetTooltip("Rename");
|
|
|
|
// delete
|
|
ImGui.SameLine();
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
if (_currentProfileName != DefaultProfileName && ImGui.Button(FontAwesomeIcon.Trash.ToIconString()))
|
|
{
|
|
_deletingProfileName = _currentProfileName;
|
|
}
|
|
ImGui.PopFont();
|
|
ImGuiHelper.SetTooltip("Delete");
|
|
}
|
|
|
|
// export to string
|
|
ImGuiHelper.Tab();
|
|
ImGui.SameLine();
|
|
if (ImGui.Button("Export to Clipboard", new Vector2(200, 0)))
|
|
{
|
|
string? exportString = ConfigurationManager.Instance.ExportCurrentConfigs();
|
|
if (exportString != null)
|
|
{
|
|
ImGui.SetClipboardText(exportString);
|
|
ImGui.OpenPopup("export_succes_popup");
|
|
}
|
|
}
|
|
|
|
// export success popup
|
|
if (ImGui.BeginPopup("export_succes_popup"))
|
|
{
|
|
ImGui.Text("Profile export string copied to clipboard!");
|
|
ImGui.EndPopup();
|
|
}
|
|
|
|
ImGui.SameLine();
|
|
if (ImGui.Button("Export to File", new Vector2(200, 0)))
|
|
{
|
|
ExportToFile(_currentProfileName);
|
|
}
|
|
|
|
ImGuiHelper.NewLineAndTab();
|
|
DrawAttachHudLayout(ref changed);
|
|
|
|
ImGuiHelper.NewLineAndTab();
|
|
DrawAutoSwitchSettings(ref changed);
|
|
|
|
ImGuiHelper.DrawSeparator(1, 1);
|
|
ImGuiHelper.Tab();
|
|
ImGui.Text("Create a new profile:");
|
|
|
|
ImGuiHelper.Tab();
|
|
ImGui.PushItemWidth(408);
|
|
ImGui.InputText("Profile Name", ref _newProfileName, 200);
|
|
|
|
ImGuiHelper.Tab();
|
|
ImGui.PushItemWidth(200);
|
|
ImGui.Combo("", ref _copyFromIndex, profiles, 10);
|
|
|
|
ImGui.SameLine();
|
|
if (ImGui.Button("Copy", new Vector2(200, 0)))
|
|
{
|
|
_newProfileName = _newProfileName.Trim();
|
|
if (_newProfileName.Length == 0)
|
|
{
|
|
ImGui.OpenPopup("import_error_popup");
|
|
}
|
|
else
|
|
{
|
|
_errorMessage = CloneProfile(profiles[_copyFromIndex], _newProfileName);
|
|
|
|
if (_errorMessage == null)
|
|
{
|
|
_errorMessage = SwitchToProfile(_newProfileName);
|
|
_newProfileName = "";
|
|
}
|
|
}
|
|
}
|
|
|
|
ImGuiHelper.NewLineAndTab();
|
|
if (ImGui.Button("Import From Clipboard", new Vector2(200, 0)))
|
|
{
|
|
_newProfileName = _newProfileName.Trim();
|
|
if (_newProfileName.Length == 0)
|
|
{
|
|
ImGui.OpenPopup("import_error_popup");
|
|
}
|
|
else
|
|
{
|
|
_errorMessage = ImportFromClipboard(_newProfileName);
|
|
|
|
if (_errorMessage == null)
|
|
{
|
|
_newProfileName = "";
|
|
}
|
|
}
|
|
}
|
|
|
|
ImGui.SameLine();
|
|
if (ImGui.Button("Import From File", new Vector2(200, 0)))
|
|
{
|
|
_newProfileName = _newProfileName.Trim();
|
|
if (_newProfileName.Length == 0)
|
|
{
|
|
ImGui.OpenPopup("import_error_popup");
|
|
}
|
|
else
|
|
{
|
|
ImportFromFile(_newProfileName);
|
|
}
|
|
}
|
|
|
|
// no name popup
|
|
if (ImGui.BeginPopup("import_error_popup"))
|
|
{
|
|
ImGui.Text("Please type a name for the new profile!");
|
|
ImGui.EndPopup();
|
|
}
|
|
}
|
|
|
|
ImGui.EndChild();
|
|
|
|
// error message
|
|
if (_errorMessage != null)
|
|
{
|
|
if (ImGuiHelper.DrawErrorModal(_errorMessage))
|
|
{
|
|
_errorMessage = null;
|
|
}
|
|
}
|
|
|
|
// delete confirmation
|
|
if (_deletingProfileName != null)
|
|
{
|
|
string[] lines = new string[] { "Are you sure you want to delete the profile:", " - " + _deletingProfileName };
|
|
var (didConfirm, didClose) = ImGuiHelper.DrawConfirmationModal("Delete?", lines);
|
|
|
|
if (didConfirm)
|
|
{
|
|
_errorMessage = DeleteProfile(_deletingProfileName);
|
|
changed = true;
|
|
}
|
|
|
|
if (didConfirm || didClose)
|
|
{
|
|
_deletingProfileName = null;
|
|
}
|
|
}
|
|
|
|
// reset confirmation
|
|
if (_resetingProfileName != null)
|
|
{
|
|
string[] lines = new string[] { "Are you sure you want to reset the profile:", " - " + _resetingProfileName };
|
|
var (didConfirm, didClose) = ImGuiHelper.DrawConfirmationModal("Reset?", lines);
|
|
|
|
if (didConfirm)
|
|
{
|
|
ResetProfileToDefault(_resetingProfileName, true);
|
|
ReloadCurrentProfile();
|
|
|
|
changed = true;
|
|
}
|
|
|
|
if (didConfirm || didClose)
|
|
{
|
|
_resetingProfileName = null;
|
|
}
|
|
}
|
|
|
|
// rename modal
|
|
if (_renamingProfileName != null)
|
|
{
|
|
var (didConfirm, didClose) = ImGuiHelper.DrawInputModal("Rename", "Type a new name for the profile:", ref _renamingProfileName);
|
|
|
|
if (didConfirm)
|
|
{
|
|
_errorMessage = RenameCurrentProfile(_renamingProfileName);
|
|
|
|
changed = true;
|
|
}
|
|
|
|
if (didConfirm || didClose)
|
|
{
|
|
_renamingProfileName = null;
|
|
}
|
|
}
|
|
|
|
_fileDialogManager.Draw();
|
|
|
|
return false;
|
|
}
|
|
|
|
private void DrawAutoSwitchSettings(ref bool changed)
|
|
{
|
|
Profile profile = CurrentProfile();
|
|
|
|
changed |= ImGui.Checkbox("Auto-Switch For Specific Jobs", ref profile.AutoSwitchEnabled);
|
|
|
|
if (!profile.AutoSwitchEnabled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AutoSwitchData data = profile.AutoSwitchData;
|
|
Vector2 cursorPos = ImGui.GetCursorPos() + new Vector2(14, 14);
|
|
Vector2 originalPos = cursorPos;
|
|
float maxY = 0;
|
|
|
|
JobRoles[] roles = (JobRoles[])Enum.GetValues(typeof(JobRoles));
|
|
|
|
foreach (JobRoles role in roles)
|
|
{
|
|
if (role == JobRoles.Unknown) { continue; }
|
|
if (!data.Map.ContainsKey(role)) { continue; }
|
|
|
|
bool roleValue = data.GetRoleEnabled(role);
|
|
string roleName = JobsHelper.RoleNames[role];
|
|
|
|
ImGui.SetCursorPos(cursorPos);
|
|
if (ImGui.Checkbox(roleName, ref roleValue))
|
|
{
|
|
data.SetRoleEnabled(role, roleValue);
|
|
changed = true;
|
|
}
|
|
|
|
cursorPos.Y += 40;
|
|
int jobCount = data.Map[role].Count;
|
|
|
|
for (int i = 0; i < jobCount; i++)
|
|
{
|
|
maxY = Math.Max(cursorPos.Y, maxY);
|
|
uint jobId = JobsHelper.JobsByRole[role][i];
|
|
bool jobValue = data.Map[role][i];
|
|
string jobName = JobsHelper.JobNames[jobId];
|
|
|
|
ImGui.SetCursorPos(cursorPos);
|
|
if (ImGui.Checkbox(jobName, ref jobValue))
|
|
{
|
|
data.Map[role][i] = jobValue;
|
|
changed = true;
|
|
}
|
|
|
|
cursorPos.Y += 30;
|
|
}
|
|
|
|
cursorPos.X += 100;
|
|
cursorPos.Y = originalPos.Y;
|
|
}
|
|
|
|
ImGui.SetCursorPos(new Vector2(originalPos.X, maxY + 30));
|
|
}
|
|
|
|
private void DrawAttachHudLayout(ref bool changed)
|
|
{
|
|
Profile profile = CurrentProfile();
|
|
|
|
changed |= ImGui.Checkbox("Attach HUD Layout to this profile", ref profile.AttachHudEnabled);
|
|
|
|
if (!profile.AttachHudEnabled)
|
|
{
|
|
profile.HudLayout = 0;
|
|
return;
|
|
}
|
|
|
|
int hudLayout = profile.HudLayout;
|
|
|
|
ImGui.Text("\u2514");
|
|
|
|
for (int i = 1; i <= 4; i++)
|
|
{
|
|
ImGui.SameLine();
|
|
bool hudLayoutEnabled = hudLayout == i;
|
|
if (ImGui.Checkbox("Hud Layout " + i, ref hudLayoutEnabled))
|
|
{
|
|
profile.HudLayout = i;
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// fake config object
|
|
[Disableable(false)]
|
|
[Exportable(false)]
|
|
[Shareable(false)]
|
|
[Resettable(false)]
|
|
public class ProfilesConfig : PluginConfigObject
|
|
{
|
|
public new static ProfilesConfig DefaultConfig() { return new ProfilesConfig(); }
|
|
}
|
|
|
|
// fake config page node
|
|
public class ProfilesConfigPageNode : ConfigPageNode
|
|
{
|
|
public ProfilesConfigPageNode()
|
|
{
|
|
ConfigObject = new ProfilesConfig();
|
|
}
|
|
|
|
public override bool Draw(ref bool changed)
|
|
{
|
|
return ProfilesManager.Instance?.Draw(ref changed) ?? false;
|
|
}
|
|
}
|
|
}
|