From b56447bae43f1abd158644d33b0edbbdbaaffeec Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 8 Oct 2023 15:14:35 +0200 Subject: [PATCH] Refactor code in #1423 to be cleaner --- Source/Editor/Editor.cs | 7 +- .../SourceCodeEditing/CodeEditingModule.cs | 74 +++++ .../Windows/ContentWindow.ContextMenu.cs | 275 +++++++++--------- Source/Editor/Windows/ContentWindow.cs | 76 +---- 4 files changed, 215 insertions(+), 217 deletions(-) diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs index e0c460d0c..b6eb4ca31 100644 --- a/Source/Editor/Editor.cs +++ b/Source/Editor/Editor.cs @@ -8,7 +8,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; using FlaxEditor.Content; -using FlaxEditor.Content.Import; using FlaxEditor.Content.Settings; using FlaxEditor.Content.Thumbnails; using FlaxEditor.Modules; @@ -154,12 +153,12 @@ namespace FlaxEditor public ContentFindingModule ContentFinding; /// - /// The scripts editing + /// The scripts editing. /// public CodeEditingModule CodeEditing; /// - /// The scripts documentation + /// The scripts documentation. /// public CodeDocsModule CodeDocs; @@ -179,7 +178,7 @@ namespace FlaxEditor public ProjectCacheModule ProjectCache; /// - /// The undo/redo + /// The undo/redo. /// public EditorUndo Undo; diff --git a/Source/Editor/Modules/SourceCodeEditing/CodeEditingModule.cs b/Source/Editor/Modules/SourceCodeEditing/CodeEditingModule.cs index c61fad713..d7a638598 100644 --- a/Source/Editor/Modules/SourceCodeEditing/CodeEditingModule.cs +++ b/Source/Editor/Modules/SourceCodeEditing/CodeEditingModule.cs @@ -2,8 +2,10 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Reflection; +using System.Text; using FlaxEditor.Options; using FlaxEditor.Scripting; using FlaxEngine; @@ -325,6 +327,78 @@ namespace FlaxEditor.Modules.SourceCodeEditing Editor.Instance.CodeEditing.SelectedEditor = editor; } + /// + /// Starts creating a new module + /// + internal void CreateModule(string path, string moduleName, bool editorModule, bool cpp) + { + if (string.IsNullOrEmpty(moduleName) || string.IsNullOrEmpty(path)) + { + Editor.LogWarning("Failed to create module due to no name"); + return; + } + + // Create folder + var moduleFolderPath = Path.Combine(path, moduleName); + Directory.CreateDirectory(moduleFolderPath); + + // Create module + var moduleText = "using Flax.Build;\n" + + "using Flax.Build.NativeCpp;\n" + + $"\npublic class {moduleName} : Game{(editorModule ? "Editor" : "")}Module\n" + + "{\n " + + "/// \n" + + " public override void Init()\n" + + " {\n" + + " base.Init();\n" + + "\n" + + " // C#-only scripting if false\n" + + $" BuildNativeCode = {(cpp ? "true" : "false")};\n" + + " }\n" + + "\n" + + " /// \n" + + " public override void Setup(BuildOptions options)\n" + + " {" + + "\n" + + " base.Setup(options);\n" + + "\n" + + " options.ScriptingAPI.IgnoreMissingDocumentationWarnings = true;\n" + + "\n" + + " // Here you can modify the build options for your game module\n" + + " // To reference another module use: options.PublicDependencies.Add(\"Audio\");\n" + + " // To add C++ define use: options.PublicDefinitions.Add(\"COMPILE_WITH_FLAX\");\n" + + " // To learn more see scripting documentation.\n" + + " }\n" + + "}"; + moduleText = Encoding.UTF8.GetString(Encoding.Default.GetBytes(moduleText)); + var modulePath = Path.Combine(moduleFolderPath, $"{moduleName}.Build.cs"); + File.WriteAllText(modulePath, moduleText); + Editor.Log($"Module created at {modulePath}"); + + // Get editor target and target files and add module + var files = Directory.GetFiles(path); + var targetModuleText = $"Modules.Add(\"{moduleName}\");\n "; + foreach (var file in files) + { + if (!file.Contains(".Build.cs", StringComparison.OrdinalIgnoreCase)) + continue; + var targetText = File.ReadAllText(file); + + // Skip game project if it is suppose to be an editor module + if (editorModule && targetText.Contains("GameProjectTarget", StringComparison.Ordinal)) + continue; + + // TODO: Handle edge case when there are no modules in a target + var index = targetText.IndexOf("Modules.Add"); + if (index != -1) + { + var newText = targetText.Insert(index, targetModuleText); + File.WriteAllText(file, newText); + Editor.Log($"Module added to Target: {file}"); + } + } + } + /// public override void OnUpdate() { diff --git a/Source/Editor/Windows/ContentWindow.ContextMenu.cs b/Source/Editor/Windows/ContentWindow.ContextMenu.cs index f10175cce..03873df57 100644 --- a/Source/Editor/Windows/ContentWindow.ContextMenu.cs +++ b/Source/Editor/Windows/ContentWindow.ContextMenu.cs @@ -150,145 +150,11 @@ namespace FlaxEditor.Windows cm.AddSeparator(); // Check if is source folder to add new module - if (item is ContentFolder sourceFolder && sourceFolder.ParentFolder.Node is ProjectTreeNode node) + if (folder?.ParentFolder?.Node is ProjectTreeNode parentFolderNode && folder.Node == parentFolderNode.Source) { - if (sourceFolder.Node == node.Source) - { - var button = cm.AddButton("New Module"); - button.CloseMenuOnClick = false; - button.Clicked += () => - { - var popup = new ContextMenuBase - { - Size = new Float2(230, 125), - ClipChildren = false, - CullChildren = false, - }; - popup.Show(button, new Float2(button.Width, 0)); - - var nameLabel = new Label - { - Parent = popup, - AnchorPreset = AnchorPresets.TopLeft, - Text = "Name", - HorizontalAlignment = TextAlignment.Near, - }; - nameLabel.LocalX += 10; - nameLabel.LocalY += 10; - - var nameTextBox = new TextBox - { - Parent = popup, - WatermarkText = "Module Name", - AnchorPreset = AnchorPresets.TopLeft, - IsMultiline = false, - }; - nameTextBox.LocalX += 100; - nameTextBox.LocalY += 10; - var defaultTextBoxBorderColor = nameTextBox.BorderColor; - var defaultTextBoxBorderSelectedColor = nameTextBox.BorderSelectedColor; - nameTextBox.TextChanged += () => - { - if (string.IsNullOrEmpty(nameTextBox.Text)) - { - nameTextBox.BorderColor = defaultTextBoxBorderColor; - nameTextBox.BorderSelectedColor = defaultTextBoxBorderSelectedColor; - return; - } - - var pluginPath = Path.Combine(Globals.ProjectFolder, "Source", nameTextBox.Text); - if (Directory.Exists(pluginPath)) - { - nameTextBox.BorderColor = Color.Red; - nameTextBox.BorderSelectedColor = Color.Red; - } - else - { - nameTextBox.BorderColor = defaultTextBoxBorderColor; - nameTextBox.BorderSelectedColor = defaultTextBoxBorderSelectedColor; - } - }; - - var editorLabel = new Label - { - Parent = popup, - AnchorPreset = AnchorPresets.TopLeft, - Text = "Editor", - HorizontalAlignment = TextAlignment.Near, - }; - editorLabel.LocalX += 10; - editorLabel.LocalY += 35; - - var editorCheckBox = new CheckBox() - { - Parent = popup, - AnchorPreset = AnchorPresets.TopLeft, - }; - editorCheckBox.LocalY += 35; - editorCheckBox.LocalX += 100; - - var cppLabel = new Label - { - Parent = popup, - AnchorPreset = AnchorPresets.TopLeft, - Text = "C++", - HorizontalAlignment = TextAlignment.Near, - }; - cppLabel.LocalX += 10; - cppLabel.LocalY += 60; - - var cppCheckBox = new CheckBox() - { - Parent = popup, - AnchorPreset = AnchorPresets.TopLeft, - }; - cppCheckBox.LocalY += 60; - cppCheckBox.LocalX += 100; - - var submitButton = new Button - { - Parent = popup, - AnchorPreset = AnchorPresets.TopLeft, - Text = "Create", - Width = 70, - }; - submitButton.LocalX += 40; - submitButton.LocalY += 90; - - submitButton.Clicked += () => - { - // TODO: Check all modules in project including plugins - if (Directory.Exists(Path.Combine(Globals.ProjectFolder, "Source", nameTextBox.Text))) - { - Editor.LogWarning("Cannot create module due to name conflict."); - return; - } - CreateModule(node.Source.Path, nameTextBox.Text, editorCheckBox.Checked, cppCheckBox.Checked); - nameTextBox.Clear(); - editorCheckBox.Checked = false; - cppCheckBox.Checked = false; - popup.Hide(); - }; - - var cancelButton = new Button - { - Parent = popup, - AnchorPreset = AnchorPresets.TopLeft, - Text = "Cancel", - Width = 70, - }; - cancelButton.LocalX += 120; - cancelButton.LocalY += 90; - - cancelButton.Clicked += () => - { - nameTextBox.Clear(); - editorCheckBox.Checked = false; - cppCheckBox.Checked = false; - popup.Hide(); - }; - }; - } + var button = cm.AddButton("New module"); + button.CloseMenuOnClick = false; + button.Clicked += () => NewModule(button, parentFolderNode.Source.Path); } if (!isRootFolder && !(item is ContentFolder projectFolder && projectFolder.Node is ProjectTreeNode)) @@ -456,5 +322,138 @@ namespace FlaxEditor.Windows return; } } + + private void NewModule(ContextMenuButton button, string path) + { + var popup = new ContextMenuBase + { + Size = new Float2(230, 125), + ClipChildren = false, + CullChildren = false, + }; + popup.Show(button, new Float2(button.Width, 0)); + + var nameLabel = new Label + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + Text = "Name", + HorizontalAlignment = TextAlignment.Near, + }; + nameLabel.LocalX += 10; + nameLabel.LocalY += 10; + + var nameTextBox = new TextBox + { + Parent = popup, + WatermarkText = "Module Name", + AnchorPreset = AnchorPresets.TopLeft, + IsMultiline = false, + }; + nameTextBox.LocalX += 100; + nameTextBox.LocalY += 10; + var defaultTextBoxBorderColor = nameTextBox.BorderColor; + var defaultTextBoxBorderSelectedColor = nameTextBox.BorderSelectedColor; + nameTextBox.TextChanged += () => + { + if (string.IsNullOrEmpty(nameTextBox.Text)) + { + nameTextBox.BorderColor = defaultTextBoxBorderColor; + nameTextBox.BorderSelectedColor = defaultTextBoxBorderSelectedColor; + return; + } + + var pluginPath = Path.Combine(Globals.ProjectFolder, "Source", nameTextBox.Text); + if (Directory.Exists(pluginPath)) + { + nameTextBox.BorderColor = Color.Red; + nameTextBox.BorderSelectedColor = Color.Red; + } + else + { + nameTextBox.BorderColor = defaultTextBoxBorderColor; + nameTextBox.BorderSelectedColor = defaultTextBoxBorderSelectedColor; + } + }; + + var editorLabel = new Label + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + Text = "Editor", + HorizontalAlignment = TextAlignment.Near, + }; + editorLabel.LocalX += 10; + editorLabel.LocalY += 35; + + var editorCheckBox = new CheckBox + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + }; + editorCheckBox.LocalY += 35; + editorCheckBox.LocalX += 100; + + var cppLabel = new Label + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + Text = "C++", + HorizontalAlignment = TextAlignment.Near, + }; + cppLabel.LocalX += 10; + cppLabel.LocalY += 60; + + var cppCheckBox = new CheckBox + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + }; + cppCheckBox.LocalY += 60; + cppCheckBox.LocalX += 100; + + var submitButton = new Button + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + Text = "Create", + Width = 70, + }; + submitButton.LocalX += 40; + submitButton.LocalY += 90; + submitButton.Clicked += () => + { + // TODO: Check all modules in project including plugins + if (Directory.Exists(Path.Combine(Globals.ProjectFolder, "Source", nameTextBox.Text))) + { + Editor.LogWarning("Cannot create module due to name conflict."); + return; + } + Editor.CodeEditing.CreateModule(path, nameTextBox.Text, editorCheckBox.Checked, cppCheckBox.Checked); + nameTextBox.Clear(); + editorCheckBox.Checked = false; + cppCheckBox.Checked = false; + popup.Hide(); + button.ParentContextMenu.Hide(); + }; + + var cancelButton = new Button + { + Parent = popup, + AnchorPreset = AnchorPresets.TopLeft, + Text = "Cancel", + Width = 70, + }; + cancelButton.LocalX += 120; + cancelButton.LocalY += 90; + cancelButton.Clicked += () => + { + nameTextBox.Clear(); + editorCheckBox.Checked = false; + cppCheckBox.Checked = false; + popup.Hide(); + button.ParentContextMenu.Hide(); + }; + } } } diff --git a/Source/Editor/Windows/ContentWindow.cs b/Source/Editor/Windows/ContentWindow.cs index 1210b021c..6b5855238 100644 --- a/Source/Editor/Windows/ContentWindow.cs +++ b/Source/Editor/Windows/ContentWindow.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; -using System.Text; using System.Xml; using FlaxEditor.Content; using FlaxEditor.Content.GUI; @@ -330,7 +329,7 @@ namespace FlaxEditor.Windows b.Checked = ShowPluginsFiles; b.CloseMenuOnClick = false; b.AutoCheck = true; - + b = show.ContextMenu.AddButton("Generated files", () => ShowGeneratedFiles = !ShowGeneratedFiles); b.TooltipText = "Shows generated files"; b.Checked = ShowGeneratedFiles; @@ -756,79 +755,6 @@ namespace FlaxEditor.Windows Editor.ContentImporting.Import(importFiles, CurrentViewFolder); } - /// - /// Starts creating a new module - /// - private async void CreateModule(string path, string moduleName, bool editorModule, bool cpp) - { - if (string.IsNullOrEmpty(moduleName) || string.IsNullOrEmpty(path)) - { - Editor.LogWarning("Failed to create module due to no name"); - return; - } - - // Create folder - var moduleFolderPath = Path.Combine(path, moduleName); - Directory.CreateDirectory(moduleFolderPath); - - // Create module - var moduleText = "using Flax.Build;\n" + - "using Flax.Build.NativeCpp;\n" + - $"\npublic class {moduleName} : Game{(editorModule ? "Editor" : "")}Module\n" + - "{\n " + - "/// \n" + - " public override void Init()\n" + - " {\n" + - " base.Init();\n" + - "\n" + - " // C#-only scripting if false\n" + - $" BuildNativeCode = {(cpp ? "true" : "false")};\n" + - " }\n" + - "\n" + - " /// \n" + - " public override void Setup(BuildOptions options)\n" + - " {" + - "\n" + - " base.Setup(options);\n" + - "\n" + - " options.ScriptingAPI.IgnoreMissingDocumentationWarnings = true;\n" + - "\n" + - " // Here you can modify the build options for your game module\n" + - " // To reference another module use: options.PublicDependencies.Add(\"Audio\");\n" + - " // To add C++ define use: options.PublicDefinitions.Add(\"COMPILE_WITH_FLAX\");\n" + - " // To learn more see scripting documentation.\n" + - " }\n" + - "}"; - moduleText = Encoding.UTF8.GetString(Encoding.Default.GetBytes(moduleText)); - var modulePath = Path.Combine(moduleFolderPath, $"{moduleName}.Build.cs"); - await File.WriteAllTextAsync(modulePath, moduleText); - Editor.Log($"Module created at {modulePath}"); - - // Get editor target and target files and add module - var files = Directory.GetFiles(path); - var targetModuleText = $"Modules.Add(\"{moduleName}\");\n "; - foreach (var file in files) - { - if (!file.Contains(".Build.cs", StringComparison.OrdinalIgnoreCase)) - continue; - - var targetText = await File.ReadAllTextAsync(file); - - // Skip game project if it is suppose to be an editor module - if (editorModule && targetText.Contains("GameProjectTarget", StringComparison.Ordinal)) - continue; - - // TODO: Handle edge case when there are no modules in a target - var index = targetText.IndexOf("Modules.Add"); - if (index != -1) - { - var newText = targetText.Insert(index, targetModuleText); - await File.WriteAllTextAsync(file, newText); - Editor.Log($"Module added to Target: {file}"); - } - } - } - /// /// Starts creating the folder. ///