Merge branch 'auto-module' of https://github.com/Tryibion/FlaxEngine into Tryibion-auto-module
# Conflicts: # Source/Editor/Windows/ContentWindow.ContextMenu.cs
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using FlaxEditor.Content;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.Assertions;
|
||||
using FlaxEngine.GUI;
|
||||
using FlaxEngine.Json;
|
||||
|
||||
namespace FlaxEditor.Windows
|
||||
@@ -145,9 +147,152 @@ namespace FlaxEditor.Windows
|
||||
cm.AddButton("Refresh all thumbnails", RefreshViewItemsThumbnails);
|
||||
}
|
||||
|
||||
cm.AddSeparator();
|
||||
|
||||
// Check if is source folder to add new module
|
||||
if (item is ContentFolder sourceFolder && sourceFolder.ParentFolder.Node is ProjectTreeNode node)
|
||||
{
|
||||
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();
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (!isRootFolder && !(item is ContentFolder projectFolder && projectFolder.Node is ProjectTreeNode))
|
||||
{
|
||||
cm.AddSeparator();
|
||||
cm.AddButton("New folder", NewFolder);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ 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;
|
||||
@@ -756,7 +757,80 @@ namespace FlaxEditor.Windows
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stars creating the folder.
|
||||
/// Starts creating a new module
|
||||
/// </summary>
|
||||
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 " +
|
||||
"/// <inheritdoc />\n" +
|
||||
" public override void Init()\n" +
|
||||
" {\n" +
|
||||
" base.Init();\n" +
|
||||
"\n" +
|
||||
" // C#-only scripting if false\n" +
|
||||
$" BuildNativeCode = {(cpp ? "true" : "false")};\n" +
|
||||
" }\n" +
|
||||
"\n" +
|
||||
" /// <inheritdoc />\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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts creating the folder.
|
||||
/// </summary>
|
||||
public void NewFolder()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user