diff --git a/FrostyEditor/Windows/MainWindow.xaml b/FrostyEditor/Windows/MainWindow.xaml index c782b8cba..eb8c8029e 100644 --- a/FrostyEditor/Windows/MainWindow.xaml +++ b/FrostyEditor/Windows/MainWindow.xaml @@ -20,13 +20,42 @@ + - + + + + + + + + + + + + + + + + + - @@ -67,7 +96,7 @@ - + diff --git a/FrostyEditor/Windows/MainWindow.xaml.cs b/FrostyEditor/Windows/MainWindow.xaml.cs index 7222a2c60..6cc5e9798 100644 --- a/FrostyEditor/Windows/MainWindow.xaml.cs +++ b/FrostyEditor/Windows/MainWindow.xaml.cs @@ -24,10 +24,11 @@ using FrostyCore; using FrostySdk; using FrostySdk.IO; -using FrostySdk.Managers; using FrostySdk.Managers.Entries; using Microsoft.Win32; using Bookmarks = Frosty.Core.Bookmarks; +using Frosty.Core.Attributes; +using Frosty.Core.Misc; namespace FrostyEditor.Windows { @@ -1142,7 +1143,62 @@ private void contextMenuBookmarkItemFind_Click(object sender, RoutedEventArgs e) target.Target.NavigateTo(false); } -#endregion + private IBlueprintEditorHandler blueprintEditorHandler = App.PluginManager.BlueprintEditorOpenAction.Count() == 0 ? new DefaultBlueprintEditorHandler() : App.PluginManager.BlueprintEditorOpenAction.First(); + + private void contextMenuBookmarkItemOpenBlueprintEditor_Click(object sender, RoutedEventArgs e) + { + if (BookmarkTreeView.SelectedItem == null) + return; + Bookmarks.BookmarkItem target = BookmarkTreeView.SelectedItem as Bookmarks.BookmarkItem; + if (target.Target is Bookmarks.AssetBookmarkTarget assetTarget) + { + if (assetTarget.Asset is EbxAssetEntry entry) + { + if (entry != null) + { + blueprintEditorHandler.OpenAssetAsGraph(entry); + } + } + } + } + + private void contextMenuBookmarkItemCopyGUID_Click(object sender, RoutedEventArgs e) + { + if (BookmarkTreeView.SelectedItem == null) + return; + Bookmarks.BookmarkItem target = BookmarkTreeView.SelectedItem as Bookmarks.BookmarkItem; + if (target.Target is Bookmarks.AssetBookmarkTarget assetTarget) + { + if (assetTarget.Asset is EbxAssetEntry entry) + { + if (entry != null) + { + EbxAsset asset = App.AssetManager.GetEbx(entry.Name); + App.Logger.Log(asset.FileGuid.ToString()); + Clipboard.SetText(asset.FileGuid.ToString()); + } + } + } + } + + private void contextMenuBookmarkItemCopyPath_Click(object sender, RoutedEventArgs e) + { + if (BookmarkTreeView.SelectedItem == null) + return; + Bookmarks.BookmarkItem target = BookmarkTreeView.SelectedItem as Bookmarks.BookmarkItem; + if (target.Target is Bookmarks.AssetBookmarkTarget assetTarget) + { + if (assetTarget.Asset is EbxAssetEntry entry) + { + if (entry != null) + { + Clipboard.SetText(entry.Name); + } + } + } + } + + #endregion #region -- Bookmarks -- diff --git a/FrostyPlugin/Attributes/RegisterBlueprintEditorHandlerAttribute.cs b/FrostyPlugin/Attributes/RegisterBlueprintEditorHandlerAttribute.cs new file mode 100644 index 000000000..ebac5fcc5 --- /dev/null +++ b/FrostyPlugin/Attributes/RegisterBlueprintEditorHandlerAttribute.cs @@ -0,0 +1,27 @@ +using FrostySdk.Ebx; +using FrostySdk.Managers.Entries; +using System; +using System.Windows.Controls; +using System.Windows.Media; + +namespace Frosty.Core.Attributes +{ + /// + /// This attribute registers the method for opening files in the Blueprint Editor. + /// + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = true)] + public class RegisterBlueprintEditorHandlerAttribute : Attribute + { + public Type classToHandle { get; set; } + + public RegisterBlueprintEditorHandlerAttribute(Type type) + { + classToHandle = type; + } + } + + public interface IBlueprintEditorHandler + { + void OpenAssetAsGraph(EbxAssetEntry asset); + } +} diff --git a/FrostyPlugin/Controls/Editors/FrostyPointerRefEditor.cs b/FrostyPlugin/Controls/Editors/FrostyPointerRefEditor.cs index dbc04776c..bfeb9265f 100644 --- a/FrostyPlugin/Controls/Editors/FrostyPointerRefEditor.cs +++ b/FrostyPlugin/Controls/Editors/FrostyPointerRefEditor.cs @@ -18,6 +18,9 @@ using System.Windows.Input; using FrostySdk.Managers.Entries; +using Frosty.Core.Attributes; +using Frosty.Core.Misc; + //using System.IO; namespace Frosty.Core.Controls.Editors @@ -270,6 +273,7 @@ private void Popup_DropDownOpened(object sender, EventArgs e) Button clearButton = (popupMenu.FindName("PART_ClearButton") as Button); Button openButton = (popupMenu.FindName("PART_OpenButton") as Button); Button findButton = (popupMenu.FindName("PART_FindButton") as Button); + Button blueprintEditorButton = (popupMenu.FindName("PART_BlueprintEditorButton") as Button); Button createButton = (popupMenu.FindName("PART_CreateButton") as Button); TextBlock textBlock = (popupMenu.FindName("PART_TextBlock") as TextBlock); Border separator = (popupMenu.FindName("PART_Separator") as Border); @@ -278,11 +282,13 @@ private void Popup_DropDownOpened(object sender, EventArgs e) clearButton.Click -= ClearButton_Click; findButton.Click -= FindButton_Click; + blueprintEditorButton.Click -= BlueprintEditorButton_Click; openButton.Click -= OpenButton_Click; createButton.Click -= CreateButton_Click; clearButton.Click += ClearButton_Click; findButton.Click += FindButton_Click; + blueprintEditorButton.Click += BlueprintEditorButton_Click; openButton.Click += OpenButton_Click; createButton.Click += CreateButton_Click; filter.TextChanged += Filter_TextChanged; @@ -290,6 +296,7 @@ private void Popup_DropDownOpened(object sender, EventArgs e) PointerRef ptrRef = (PointerRef)Value; clearButton.IsEnabled = ptrRef.Type != PointerRefType.Null; findButton.IsEnabled = !(ptrRef.Type == PointerRefType.Internal || ptrRef.Type == PointerRefType.Null); + blueprintEditorButton.IsEnabled = !(ptrRef.Type == PointerRefType.Internal || ptrRef.Type == PointerRefType.Null); openButton.IsEnabled = !(ptrRef.Type == PointerRefType.Internal || ptrRef.Type == PointerRefType.Null); createButton.IsEnabled = canCreate; textBlock.Text = "Assign from " + ((isInternal) ? "self" : App.AssetManager.GetEbxEntry(assignFileGuid).Name); @@ -383,6 +390,23 @@ private void FindButton_Click(object sender, RoutedEventArgs e) popup.IsDropDownOpen = false; } + private void BlueprintEditorButton_Click(object sender, RoutedEventArgs e) + { + IEnumerable handlerEnumerable = App.PluginManager.BlueprintEditorOpenAction; + IBlueprintEditorHandler handlerClass = handlerEnumerable.Count() == 0 ? new DefaultBlueprintEditorHandler() : handlerEnumerable.First(); + PointerRef ptr = (PointerRef)Value; + if (ptr.Type == PointerRefType.External) + { + EbxAssetEntry asset = App.AssetManager.GetEbxEntry(ptr.External.FileGuid); + if (asset == null) + { + return; + } + handlerClass.OpenAssetAsGraph(asset); + } + popup.IsDropDownOpen = false; + } + /// /// Performs the actual assinging for either internal or external selection /// diff --git a/FrostyPlugin/Controls/FrostyAssetEditor.cs b/FrostyPlugin/Controls/FrostyAssetEditor.cs index 02d0b02ee..613514d79 100644 --- a/FrostyPlugin/Controls/FrostyAssetEditor.cs +++ b/FrostyPlugin/Controls/FrostyAssetEditor.cs @@ -1,13 +1,18 @@ -using Frosty.Core.Windows; +using Frosty.Core.Attributes; +using Frosty.Core.Misc; +using Frosty.Core.Windows; using FrostySdk; +using FrostySdk.Ebx; using FrostySdk.Interfaces; using FrostySdk.IO; using FrostySdk.Managers; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; +using System.Windows.Controls.Primitives; using System.Windows.Media; using FrostySdk.Managers.Entries; using Frosty.Controls; @@ -199,7 +204,14 @@ public virtual void Closed() public virtual List RegisterToolbarItems() { - return new List() { new ToolbarItem("View Instances", "View class instances", null, new RelayCommand(ViewInstances_Click, ViewInstances_CanClick)) }; + return new List() { + new ToolbarItem($"View Instances ({asset.RootObjects.Count()})", "View class instances", "Images/Database.png", new RelayCommand(ViewInstances_Click, ViewInstances_CanClick)), + new ToolbarItem("Open in Blueprint Editor", "Open this file in the graph editor (if available)", "Images/Grid.png", new RelayCommand((_) => { + IEnumerable handlerEnumerable = App.PluginManager.BlueprintEditorOpenAction; + IBlueprintEditorHandler handlerClass = handlerEnumerable.Count() == 0 ? new DefaultBlueprintEditorHandler() : handlerEnumerable.First(); + handlerClass.OpenAssetAsGraph(AssetEntry as EbxAssetEntry); + }, (_) => AssetEntry is EbxAssetEntry)) + }; } private void ViewInstances_Click(object state) diff --git a/FrostyPlugin/FrostyCore.csproj b/FrostyPlugin/FrostyCore.csproj index 764bab647..4dc21ae7c 100644 --- a/FrostyPlugin/FrostyCore.csproj +++ b/FrostyPlugin/FrostyCore.csproj @@ -122,6 +122,7 @@ + @@ -150,6 +151,7 @@ + diff --git a/FrostyPlugin/Managers/PluginManager.cs b/FrostyPlugin/Managers/PluginManager.cs index 1eb8a11af..ecc4d25f3 100644 --- a/FrostyPlugin/Managers/PluginManager.cs +++ b/FrostyPlugin/Managers/PluginManager.cs @@ -170,6 +170,10 @@ public sealed class PluginManager public PluginManagerType ManagerType => m_managerType; public IEnumerable CustomAssetHandlers => m_customAssetHandlers.Keys; + + private List m_blueprintEditorOpenAction = new List(); + + public IEnumerable BlueprintEditorOpenAction => m_blueprintEditorOpenAction; private readonly Dictionary m_definitions = new Dictionary(); private readonly List m_menuExtensions = new List(); @@ -670,6 +674,11 @@ private void LoadDefinitionsFromAssembly(PluginLoadType loadType, Assembly assem { App.AssetManager.RegisterCustomAssetManager(attr12.CustomAssetManagerType, attr12.CustomAssetManagerClassType); } + + else if (tmpAttr is RegisterBlueprintEditorHandlerAttribute attr13) + { + m_blueprintEditorOpenAction.Add((IBlueprintEditorHandler)Activator.CreateInstance(attr13.classToHandle)); + } } } } diff --git a/FrostyPlugin/Misc/DefaultBlueprintEditorHandler.cs b/FrostyPlugin/Misc/DefaultBlueprintEditorHandler.cs new file mode 100644 index 000000000..b3c2fe91f --- /dev/null +++ b/FrostyPlugin/Misc/DefaultBlueprintEditorHandler.cs @@ -0,0 +1,19 @@ +using Frosty.Controls; +using Frosty.Core.Attributes; +using FrostySdk.Managers.Entries; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Frosty.Core.Misc +{ + public class DefaultBlueprintEditorHandler : IBlueprintEditorHandler + { + public void OpenAssetAsGraph(EbxAssetEntry asset) + { + FrostyMessageBox.Show("Missing valid handler for opening blueprint editor. Please make sure you have a version of the blueprint editor that supports this feature.", "Open in Blueprint Editor"); + } + } +} diff --git a/FrostyPlugin/Themes/Generic.xaml b/FrostyPlugin/Themes/Generic.xaml index bb4a5f05d..634a3d970 100644 --- a/FrostyPlugin/Themes/Generic.xaml +++ b/FrostyPlugin/Themes/Generic.xaml @@ -808,6 +808,7 @@