From ef6c7014e42f93e38f4b192041cce4e0ab320da4 Mon Sep 17 00:00:00 2001
From: RisaDev <151885272+RisaDev@users.noreply.github.com>
Date: Sun, 16 Jun 2024 02:58:17 +0300
Subject: [PATCH] Added button to jump to template editing from profile tab,
made TemplateManager IDisposable
---
.../Templates/Events/TemplateEditorEvent.cs | 33 ++++++++
CustomizePlus/Templates/TemplateManager.cs | 7 +-
.../UI/Windows/MainWindow/MainWindow.cs | 51 ++++++++++++-
.../MainWindow/Tabs/Profiles/ProfilePanel.cs | 32 ++++++--
.../Tabs/Templates/TemplatePanel.cs | 75 ++++++++++++++++---
5 files changed, 178 insertions(+), 20 deletions(-)
create mode 100644 CustomizePlus/Templates/Events/TemplateEditorEvent.cs
diff --git a/CustomizePlus/Templates/Events/TemplateEditorEvent.cs b/CustomizePlus/Templates/Events/TemplateEditorEvent.cs
new file mode 100644
index 0000000..a0afd2c
--- /dev/null
+++ b/CustomizePlus/Templates/Events/TemplateEditorEvent.cs
@@ -0,0 +1,33 @@
+using CustomizePlus.Templates.Data;
+using OtterGui.Classes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CustomizePlus.Templates.Events;
+
+///
+/// Triggered when something related to template editor happens
+///
+public class TemplateEditorEvent() : EventWrapper(nameof(TemplateEditorEvent))
+{
+ public enum Type
+ {
+ ///
+ /// Called when something requests editor to be enabled.
+ ///
+ EditorEnableRequested,
+ ///
+ /// Called when something requests editor to be enabled. Stage 2 - logic after tab has been switched.
+ ///
+ EditorEnableRequestedStage2
+ }
+
+ public enum Priority
+ {
+ MainWindow = -1,
+ TemplatePanel
+ }
+}
\ No newline at end of file
diff --git a/CustomizePlus/Templates/TemplateManager.cs b/CustomizePlus/Templates/TemplateManager.cs
index 1df8a31..a41dda6 100644
--- a/CustomizePlus/Templates/TemplateManager.cs
+++ b/CustomizePlus/Templates/TemplateManager.cs
@@ -13,7 +13,7 @@ using System.Linq;
namespace CustomizePlus.Templates;
-public class TemplateManager
+public class TemplateManager : IDisposable
{
private readonly SaveService _saveService;
private readonly Logger _logger;
@@ -41,6 +41,11 @@ public class TemplateManager
LoadTemplates();
}
+ public void Dispose()
+ {
+ _reloadEvent.Unsubscribe(OnReload);
+ }
+
public Template? GetTemplate(Guid templateId) => _templates.FirstOrDefault(d => d.UniqueId == templateId);
public void LoadTemplates()
diff --git a/CustomizePlus/UI/Windows/MainWindow/MainWindow.cs b/CustomizePlus/UI/Windows/MainWindow/MainWindow.cs
index ab74f95..1d7f639 100644
--- a/CustomizePlus/UI/Windows/MainWindow/MainWindow.cs
+++ b/CustomizePlus/UI/Windows/MainWindow/MainWindow.cs
@@ -16,6 +16,9 @@ using CustomizePlus.Templates;
using ECommons.ImGuiMethods;
using static System.Windows.Forms.AxHost;
using Dalamud.Interface.Colors;
+using CustomizePlus.Templates.Events;
+using CustomizePlus.Templates.Data;
+using ECommons.Schedulers;
namespace CustomizePlus.UI.Windows.MainWindow;
@@ -34,6 +37,15 @@ public class MainWindow : Window, IDisposable
private readonly PluginConfiguration _configuration;
private readonly HookingService _hookingService;
+ private readonly TemplateEditorEvent _templateEditorEvent;
+
+ ///
+ /// Used to force the main window to switch to specific tab
+ ///
+ private string? _switchToTab = null;
+
+ private Action? _actionAfterTabSwitch = null;
+
public MainWindow(
DalamudPluginInterface pluginInterface,
SettingsTab settingsTab,
@@ -45,7 +57,8 @@ public class MainWindow : Window, IDisposable
PluginStateBlock pluginStateBlock,
TemplateEditorManager templateEditorManager,
PluginConfiguration configuration,
- HookingService hookingService
+ HookingService hookingService,
+ TemplateEditorEvent templateEditorEvent
) : base($"Customize+ v{Plugin.Version}###CPlusMainWindow")
{
_settingsTab = settingsTab;
@@ -61,6 +74,10 @@ public class MainWindow : Window, IDisposable
_configuration = configuration;
_hookingService = hookingService;
+ _templateEditorEvent = templateEditorEvent;
+
+ _templateEditorEvent.Subscribe(OnTemplateEditorEvent, TemplateEditorEvent.Priority.MainWindow);
+
pluginInterface.UiBuilder.DisableGposeUiHide = true;
SizeConstraints = new WindowSizeConstraints()
{
@@ -73,7 +90,7 @@ public class MainWindow : Window, IDisposable
public void Dispose()
{
- //throw new NotImplementedException();
+ _templateEditorEvent.Unsubscribe(OnTemplateEditorEvent);
}
public override void Draw()
@@ -83,13 +100,21 @@ public class MainWindow : Window, IDisposable
using (var disabled = ImRaii.Disabled(_hookingService.RenderHookFailed || _hookingService.MovementHookFailed))
{
LockWindowClosureIfNeeded();
- ImGuiEx.EzTabBar("##tabs", [
+ ImGuiEx.EzTabBar("##tabs", null, _switchToTab, [
("Settings", _settingsTab.Draw, null, true),
("Templates", _templatesTab.Draw, null, true),
("Profiles", _profilesTab.Draw, null, true),
(_configuration.DebuggingModeEnabled ? "IPC Test" : null, _ipcTestTab.Draw, ImGuiColors.DalamudGrey, true),
(_configuration.DebuggingModeEnabled ? "State monitoring" : null, _stateMonitoringTab.Draw, ImGuiColors.DalamudGrey, true),
]);
+
+ _switchToTab = null;
+
+ if (_actionAfterTabSwitch != null)
+ {
+ _actionAfterTabSwitch();
+ _actionAfterTabSwitch = null;
+ }
}
_pluginStateBlock.Draw(yPos);
@@ -108,4 +133,24 @@ public class MainWindow : Window, IDisposable
RespectCloseHotkey = true;
}
}
+
+ private void OnTemplateEditorEvent(TemplateEditorEvent.Type type, Template? template)
+ {
+ if (type != TemplateEditorEvent.Type.EditorEnableRequested)
+ return;
+
+ if (template == null)
+ return;
+
+ if (!template.IsWriteProtected && !_templateEditorManager.IsEditorActive)
+ {
+ new TickScheduler(() =>
+ {
+ _switchToTab = "Templates";
+
+ //To make sure the tab has switched, ugly but imgui is shit and I don't trust it.
+ _actionAfterTabSwitch = () => { _templateEditorEvent.Invoke(TemplateEditorEvent.Type.EditorEnableRequestedStage2, template); };
+ });
+ }
+ }
}
diff --git a/CustomizePlus/UI/Windows/MainWindow/Tabs/Profiles/ProfilePanel.cs b/CustomizePlus/UI/Windows/MainWindow/Tabs/Profiles/ProfilePanel.cs
index 71a5dfd..526a8a1 100644
--- a/CustomizePlus/UI/Windows/MainWindow/Tabs/Profiles/ProfilePanel.cs
+++ b/CustomizePlus/UI/Windows/MainWindow/Tabs/Profiles/ProfilePanel.cs
@@ -7,15 +7,12 @@ 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;
+using CustomizePlus.Templates.Events;
namespace CustomizePlus.UI.Windows.MainWindow.Tabs.Profiles;
@@ -26,6 +23,7 @@ public class ProfilePanel
private readonly PluginConfiguration _configuration;
private readonly TemplateCombo _templateCombo;
private readonly TemplateEditorManager _templateEditorManager;
+ private readonly TemplateEditorEvent _templateEditorEvent;
private string? _newName;
private string? _newCharacterName;
@@ -43,13 +41,15 @@ public class ProfilePanel
ProfileManager manager,
PluginConfiguration configuration,
TemplateCombo templateCombo,
- TemplateEditorManager templateEditorManager)
+ TemplateEditorManager templateEditorManager,
+ TemplateEditorEvent templateEditorEvent)
{
_selector = selector;
_manager = manager;
_configuration = configuration;
_templateCombo = templateCombo;
_templateEditorManager = templateEditorManager;
+ _templateEditorEvent = templateEditorEvent;
}
public void Draw()
@@ -247,7 +247,7 @@ public class ProfilePanel
private void DrawTemplateArea()
{
- using var table = ImRaii.Table("SetTable", 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollX | ImGuiTableFlags.ScrollY);
+ using var table = ImRaii.Table("SetTable", 4, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollX | ImGuiTableFlags.ScrollY);
if (!table)
return;
@@ -256,6 +256,8 @@ public class ProfilePanel
ImGui.TableSetupColumn("Template", ImGuiTableColumnFlags.WidthFixed, 220 * ImGuiHelpers.GlobalScale);
+ ImGui.TableSetupColumn("##editbtn", ImGuiTableColumnFlags.WidthFixed, 120 * ImGuiHelpers.GlobalScale);
+
ImGui.TableHeadersRow();
//warn: .ToList() might be performance critical at some point
@@ -277,6 +279,24 @@ public class ProfilePanel
ImGui.TableNextColumn();
_templateCombo.Draw(_selector.Selected!, template, idx);
DrawDragDrop(_selector.Selected!, idx);
+ ImGui.TableNextColumn();
+
+ var disabledCondition = _templateEditorManager.IsEditorActive || template.IsWriteProtected;
+ using (var disabled = ImRaii.Disabled(disabledCondition))
+ {
+ if (ImGui.Button("Open in editor"))
+ _templateEditorEvent.Invoke(TemplateEditorEvent.Type.EditorEnableRequested, template);
+ ImGuiUtil.HoverTooltip("Open this template in the template editor");
+ }
+
+ if(disabledCondition)
+ {
+ ImGui.SameLine();
+ ImGui.PushStyleColor(ImGuiCol.Text, Constants.Colors.Warning);
+ ImGuiUtil.PrintIcon(FontAwesomeIcon.ExclamationTriangle);
+ ImGui.PopStyleColor();
+ ImGuiUtil.HoverTooltip("Can not be edited because this template is either write protected or template editor is already enabled.");
+ }
}
ImGui.TableNextColumn();
diff --git a/CustomizePlus/UI/Windows/MainWindow/Tabs/Templates/TemplatePanel.cs b/CustomizePlus/UI/Windows/MainWindow/Tabs/Templates/TemplatePanel.cs
index 12c4a6c..a6a7c89 100644
--- a/CustomizePlus/UI/Windows/MainWindow/Tabs/Templates/TemplatePanel.cs
+++ b/CustomizePlus/UI/Windows/MainWindow/Tabs/Templates/TemplatePanel.cs
@@ -15,10 +15,12 @@ using CustomizePlus.Configuration.Data;
using CustomizePlus.Core.Helpers;
using CustomizePlus.Templates.Data;
using OtterGui.Log;
+using CustomizePlus.Templates.Events;
+using ECommons.Schedulers;
namespace CustomizePlus.UI.Windows.MainWindow.Tabs.Templates;
-public class TemplatePanel
+public class TemplatePanel : IDisposable
{
private readonly TemplateFileSystemSelector _selector;
private readonly TemplateManager _manager;
@@ -28,9 +30,16 @@ public class TemplatePanel
private readonly PopupSystem _popupSystem;
private readonly Logger _logger;
+ private readonly TemplateEditorEvent _editorEvent;
+
private string? _newName;
private Template? _changedTemplate;
+ ///
+ /// Set to true if we received OnEditorEvent EditorEnableRequested and waiting for selector value to be changed.
+ ///
+ private bool _isEditorEnablePending = false;
+
private string SelectionName
=> _selector.Selected == null ? "No Selection" : _selector.IncognitoMode ? _selector.Selected.Incognito : _selector.Selected.Name.Text;
@@ -41,7 +50,8 @@ public class TemplatePanel
PluginConfiguration configuration,
MessageService messageService,
PopupSystem popupSystem,
- Logger logger)
+ Logger logger,
+ TemplateEditorEvent editorEvent)
{
_selector = selector;
_manager = manager;
@@ -51,6 +61,11 @@ public class TemplatePanel
_popupSystem = popupSystem;
_logger = logger;
+ _editorEvent = editorEvent;
+
+ _editorEvent.Subscribe(OnEditorEvent, TemplateEditorEvent.Priority.TemplatePanel);
+
+ _selector.SelectionChanged += SelectorSelectionChanged;
}
public void Draw()
@@ -67,6 +82,11 @@ public class TemplatePanel
}
}
+ public void Dispose()
+ {
+ _editorEvent.Unsubscribe(OnEditorEvent);
+ }
+
private HeaderDrawer.Button LockButton()
=> _selector.Selected == null
? HeaderDrawer.Button.Invisible
@@ -167,17 +187,23 @@ public class TemplatePanel
private void DrawEditorToggle()
{
+ (bool isEditorAllowed, bool isEditorActive) = CanToggleEditor();
+
if (ImGuiUtil.DrawDisabledButton($"{(_boneEditor.IsEditorActive ? "Finish" : "Start")} bone editing", Vector2.Zero,
- "Toggle the bone editor for this template",
- (_selector.Selected?.IsWriteProtected ?? true) || !_configuration.PluginEnabled))
+ "Toggle the bone editor for this template", !isEditorAllowed))
{
- if (!_boneEditor.IsEditorActive)
+ if (!isEditorActive)
_boneEditor.EnableEditor(_selector.Selected!);
else
_boneEditor.DisableEditor();
}
}
+ private (bool isEditorAllowed, bool isEditorActive) CanToggleEditor()
+ {
+ return ((!_selector.Selected?.IsWriteProtected ?? false) || _configuration.PluginEnabled, _boneEditor.IsEditorActive);
+ }
+
private void DrawBasicSettings()
{
using (var style = ImRaii.PushStyle(ImGuiStyleVar.ButtonTextAlign, new Vector2(0, 0.5f)))
@@ -214,11 +240,6 @@ public class TemplatePanel
}
}
- /*private void SetFromClipboard()
- {
-
- }*/
-
private void ExportToClipboard()
{
try
@@ -232,4 +253,38 @@ public class TemplatePanel
_popupSystem.ShowPopup(PopupSystem.Messages.ActionError);
}
}
+
+
+ private void SelectorSelectionChanged(Template? oldSelection, Template? newSelection, in TemplateFileSystemSelector.TemplateState state)
+ {
+ if (!_isEditorEnablePending)
+ return;
+
+ _isEditorEnablePending = false;
+
+ _boneEditor.EnableEditor(_selector.Selected!);
+ }
+
+ private void OnEditorEvent(TemplateEditorEvent.Type type, Template? template)
+ {
+ if (type != TemplateEditorEvent.Type.EditorEnableRequestedStage2)
+ return;
+
+ if(template == null)
+ return;
+
+ (bool isEditorAllowed, bool isEditorActive) = CanToggleEditor();
+
+ if (!isEditorAllowed || isEditorActive)
+ return;
+
+ if(_selector.Selected != template)
+ {
+ _selector.SelectByValue(template);
+
+ _isEditorEnablePending = true;
+ }
+ else
+ _boneEditor.EnableEditor(_selector.Selected!);
+ }
}