Files
CustomizeTool/CustomizePlus/UI/Windows/MainWindow/Tabs/Profiles/ProfilePanel.cs
RisaDev abb92e741e More IPC work
Additional checks to make sure profile update event is not getting sent when editor and default profile is involved
Selected default profile can no longer be changed if profile set as default is enabled
Fixed "Limit to my creatures" not ignoring objects with IdentifierType != Owned
IPC test tab no longer initializes IPC if debug mode is disabled
Fixed incorrect warning priority in plugin state control
Some slight text changes
2024-03-26 00:14:29 +03:00

324 lines
13 KiB
C#

using Dalamud.Interface;
using Dalamud.Interface.Utility;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using System;
using System.Linq;
using System.Numerics;
using CustomizePlus.Profiles;
using CustomizePlus.Game.Services;
using CustomizePlus.Configuration.Data;
using CustomizePlus.Profiles.Data;
using CustomizePlus.UI.Windows.Controls;
using CustomizePlus.Templates;
using CustomizePlus.Core.Helpers;
using System.Windows.Forms;
using CustomizePlus.Core.Data;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace CustomizePlus.UI.Windows.MainWindow.Tabs.Profiles;
public class ProfilePanel
{
private readonly ProfileFileSystemSelector _selector;
private readonly ProfileManager _manager;
private readonly PluginConfiguration _configuration;
private readonly TemplateCombo _templateCombo;
private readonly TemplateEditorManager _templateEditorManager;
private string? _newName;
private string? _newCharacterName;
private Profile? _changedProfile;
private Action? _endAction;
private int _dragIndex = -1;
private string SelectionName
=> _selector.Selected == null ? "No Selection" : _selector.IncognitoMode ? _selector.Selected.Incognito : _selector.Selected.Name.Text;
public ProfilePanel(
ProfileFileSystemSelector selector,
ProfileManager manager,
PluginConfiguration configuration,
TemplateCombo templateCombo,
TemplateEditorManager templateEditorManager)
{
_selector = selector;
_manager = manager;
_configuration = configuration;
_templateCombo = templateCombo;
_templateEditorManager = templateEditorManager;
}
public void Draw()
{
using var group = ImRaii.Group();
if (_selector.SelectedPaths.Count > 1)
{
DrawMultiSelection();
}
else
{
DrawHeader();
DrawPanel();
}
}
private HeaderDrawer.Button LockButton()
=> _selector.Selected == null
? HeaderDrawer.Button.Invisible
: _selector.Selected.IsWriteProtected
? new HeaderDrawer.Button
{
Description = "Make this profile editable.",
Icon = FontAwesomeIcon.Lock,
OnClick = () => _manager.SetWriteProtection(_selector.Selected!, false)
}
: new HeaderDrawer.Button
{
Description = "Write-protect this profile.",
Icon = FontAwesomeIcon.LockOpen,
OnClick = () => _manager.SetWriteProtection(_selector.Selected!, true)
};
private void DrawHeader()
=> HeaderDrawer.Draw(SelectionName, 0, ImGui.GetColorU32(ImGuiCol.FrameBg),
0, LockButton(),
HeaderDrawer.Button.IncognitoButton(_selector.IncognitoMode, v => _selector.IncognitoMode = v));
private void DrawMultiSelection()
{
if (_selector.SelectedPaths.Count == 0)
return;
var sizeType = ImGui.GetFrameHeight();
var availableSizePercent = (ImGui.GetContentRegionAvail().X - sizeType - 4 * ImGui.GetStyle().CellPadding.X) / 100;
var sizeMods = availableSizePercent * 35;
var sizeFolders = availableSizePercent * 65;
ImGui.NewLine();
ImGui.TextUnformatted("Currently Selected Profiles");
ImGui.Separator();
using var table = ImRaii.Table("profile", 3, ImGuiTableFlags.RowBg);
ImGui.TableSetupColumn("btn", ImGuiTableColumnFlags.WidthFixed, sizeType);
ImGui.TableSetupColumn("name", ImGuiTableColumnFlags.WidthFixed, sizeMods);
ImGui.TableSetupColumn("path", ImGuiTableColumnFlags.WidthFixed, sizeFolders);
var i = 0;
foreach (var (fullName, path) in _selector.SelectedPaths.Select(p => (p.FullName(), p))
.OrderBy(p => p.Item1, StringComparer.OrdinalIgnoreCase))
{
using var id = ImRaii.PushId(i++);
ImGui.TableNextColumn();
var icon = (path is ProfileFileSystem.Leaf ? FontAwesomeIcon.FileCircleMinus : FontAwesomeIcon.FolderMinus).ToIconString();
if (ImGuiUtil.DrawDisabledButton(icon, new Vector2(sizeType), "Remove from selection.", false, true))
_selector.RemovePathFromMultiSelection(path);
ImGui.TableNextColumn();
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(path is ProfileFileSystem.Leaf l ? _selector.IncognitoMode ? l.Value.Incognito : l.Value.Name.Text : string.Empty);
ImGui.TableNextColumn();
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(_selector.IncognitoMode ? "Incognito is active" : fullName);
}
}
private void DrawPanel()
{
using var child = ImRaii.Child("##Panel", -Vector2.One, true);
if (!child || _selector.Selected == null)
return;
DrawEnabledSetting();
using (var disabled = ImRaii.Disabled(_selector.Selected?.IsWriteProtected ?? true))
{
DrawBasicSettings();
DrawTemplateArea();
}
}
private void DrawEnabledSetting()
{
var spacing = ImGui.GetStyle().ItemInnerSpacing with { X = ImGui.GetStyle().ItemSpacing.X, Y = ImGui.GetStyle().ItemSpacing.Y };
using (var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, spacing))
{
var enabled = _selector.Selected?.Enabled ?? false;
using (ImRaii.Disabled(_templateEditorManager.IsEditorActive || _templateEditorManager.IsEditorPaused))
{
if (ImGui.Checkbox("##Enabled", ref enabled))
_manager.SetEnabled(_selector.Selected!, enabled);
ImGuiUtil.LabeledHelpMarker("Enabled",
"Whether the templates in this profile should be applied at all. Only one profile can be enabled for a character at the same time.");
}
ImGui.SameLine();
var isDefault = _manager.DefaultProfile == _selector.Selected;
var isDefaultEnabled = _manager.DefaultProfile?.Enabled ?? false;
using (ImRaii.Disabled(isDefaultEnabled))
{
if (ImGui.Checkbox("##DefaultProfile", ref isDefault))
_manager.SetDefaultProfile(isDefault ? _selector.Selected! : null);
ImGuiUtil.LabeledHelpMarker("Default profile (Players and Retainers only)",
"Whether the templates in this profile are applied to all players and retainers without a specific profile. Only one profile can be default at the same time.");
}
if(isDefaultEnabled)
{
ImGui.SameLine();
ImGui.PushStyleColor(ImGuiCol.Text, Constants.Colors.Warning);
ImGuiUtil.PrintIcon(FontAwesomeIcon.ExclamationTriangle);
ImGui.PopStyleColor();
ImGuiUtil.HoverTooltip("Can only be changed while the default profile is disabled.");
}
}
}
private void DrawBasicSettings()
{
using (var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(0, 0.5f)))
{
using (var table = ImRaii.Table("BasicSettings", 2))
{
ImGui.TableSetupColumn("BasicCol1", ImGuiTableColumnFlags.WidthFixed, ImGui.CalcTextSize("lorem ipsum dolor").X);
ImGui.TableSetupColumn("BasicCol2", ImGuiTableColumnFlags.WidthStretch);
ImGuiUtil.DrawFrameColumn("Profile Name");
ImGui.TableNextColumn();
var width = new Vector2(ImGui.GetContentRegionAvail().X, 0);
var name = _newName ?? _selector.Selected!.Name;
ImGui.SetNextItemWidth(width.X);
if (!_selector.IncognitoMode)
{
if (ImGui.InputText("##ProfileName", ref name, 128))
{
_newName = name;
_changedProfile = _selector.Selected;
}
if (ImGui.IsItemDeactivatedAfterEdit() && _changedProfile != null)
{
_manager.Rename(_changedProfile, name);
_newName = null;
_changedProfile = null;
}
}
else
ImGui.TextUnformatted(_selector.Selected!.Incognito);
ImGui.TableNextRow();
ImGuiUtil.DrawFrameColumn("Character Name");
ImGui.TableNextColumn();
width = new Vector2(ImGui.GetContentRegionAvail().X - ImGui.CalcTextSize("Limit to my creatures").X - 68, 0);
name = _newCharacterName ?? _selector.Selected!.CharacterName;
ImGui.SetNextItemWidth(width.X);
if (!_selector.IncognitoMode)
{
if (ImGui.InputText("##CharacterName", ref name, 128))
{
_newCharacterName = name;
_changedProfile = _selector.Selected;
}
if (ImGui.IsItemDeactivatedAfterEdit() && _changedProfile != null)
{
_manager.ChangeCharacterName(_changedProfile, name);
_newCharacterName = null;
_changedProfile = null;
}
}
else
ImGui.TextUnformatted("Incognito active");
ImGui.SameLine();
var enabled = _selector.Selected?.LimitLookupToOwnedObjects ?? false;
if (ImGui.Checkbox("##LimitLookupToOwnedObjects", ref enabled))
_manager.SetLimitLookupToOwned(_selector.Selected!, enabled);
ImGuiUtil.LabeledHelpMarker("Limit to my creatures",
"When enabled limits the character search to only your own summons, mounts and minions.\nUseful when there is possibility there will be another character with that name owned by another player.\n* For battle chocobo use \"Chocobo\" as character name.");
}
}
}
private void DrawTemplateArea()
{
using var table = ImRaii.Table("SetTable", 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollX | ImGuiTableFlags.ScrollY);
if (!table)
return;
ImGui.TableSetupColumn("##del", ImGuiTableColumnFlags.WidthFixed, ImGui.GetFrameHeight());
ImGui.TableSetupColumn("##Index", ImGuiTableColumnFlags.WidthFixed, 30 * ImGuiHelpers.GlobalScale);
ImGui.TableSetupColumn("Template", ImGuiTableColumnFlags.WidthFixed, 220 * ImGuiHelpers.GlobalScale);
ImGui.TableHeadersRow();
//warn: .ToList() might be performance critical at some point
//the copying via ToList is done because manipulations with .Templates list result in "Collection was modified" exception here
foreach (var (template, idx) in _selector.Selected!.Templates.WithIndex().ToList())
{
using var id = ImRaii.PushId(idx);
ImGui.TableNextColumn();
var keyValid = _configuration.UISettings.DeleteTemplateModifier.IsActive();
var tt = keyValid
? "Remove this template from the profile."
: $"Remove this template from the profile.\nHold {_configuration.UISettings.DeleteTemplateModifier} to remove.";
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Trash.ToIconString(), new Vector2(ImGui.GetFrameHeight()), tt, !keyValid, true))
_endAction = () => _manager.DeleteTemplate(_selector.Selected!, idx);
ImGui.TableNextColumn();
ImGui.Selectable($"#{idx + 1:D2}");
DrawDragDrop(_selector.Selected!, idx);
ImGui.TableNextColumn();
_templateCombo.Draw(_selector.Selected!, template, idx);
DrawDragDrop(_selector.Selected!, idx);
}
ImGui.TableNextColumn();
ImGui.TableNextColumn();
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("New");
ImGui.TableNextColumn();
_templateCombo.Draw(_selector.Selected!, null, -1);
ImGui.TableNextRow();
_endAction?.Invoke();
_endAction = null;
}
private void DrawDragDrop(Profile profile, int index)
{
const string dragDropLabel = "TemplateDragDrop";
using (var target = ImRaii.DragDropTarget())
{
if (target.Success && ImGuiUtil.IsDropping(dragDropLabel))
{
if (_dragIndex >= 0)
{
var idx = _dragIndex;
_endAction = () => _manager.MoveTemplate(profile, idx, index);
}
_dragIndex = -1;
}
}
using (var source = ImRaii.DragDropSource())
{
if (source)
{
ImGui.TextUnformatted($"Moving template #{index + 1:D2}...");
if (ImGui.SetDragDropPayload(dragDropLabel, nint.Zero, 0))
{
_dragIndex = index;
}
}
}
}
}