mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Added context menu entry to create C#-Scripts.
Allow entering file name before creation
This commit is contained in:
@@ -18,19 +18,22 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
private String _name ~ delete _;
|
private String _name ~ delete _;
|
||||||
private String _defaultFileName ~ delete _;
|
private String _defaultFileName ~ delete _;
|
||||||
|
private String _fileExtension ~ delete _;
|
||||||
private CreateAssetFunc _doCreateAsset ~ delete _;
|
private CreateAssetFunc _doCreateAsset ~ delete _;
|
||||||
|
|
||||||
public delegate void CreateAssetFunc(StringView outputPath);
|
public delegate void CreateAssetFunc(StringView outputPath);
|
||||||
|
|
||||||
public StringView Name => _name;
|
public StringView Name => _name;
|
||||||
public StringView DefaultFileName => _defaultFileName;
|
public StringView DefaultFileName => _defaultFileName;
|
||||||
|
public StringView FileExtension => _fileExtension;
|
||||||
|
|
||||||
public CreateAssetFunc CreateAsset => _doCreateAsset;
|
public CreateAssetFunc CreateAsset => _doCreateAsset;
|
||||||
|
|
||||||
public this(StringView name, StringView defaultFileName, CreateAssetFunc createAsset)
|
public this(StringView name, StringView defaultFileName, StringView fileExtension, CreateAssetFunc createAsset)
|
||||||
{
|
{
|
||||||
_name = new String(name);
|
_name = new String(name);
|
||||||
_defaultFileName = new String(defaultFileName);
|
_defaultFileName = new String(defaultFileName);
|
||||||
|
_fileExtension = new String(fileExtension);
|
||||||
_doCreateAsset = createAsset;
|
_doCreateAsset = createAsset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,6 +62,10 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
public StringView SelectedFile => _selectedFile;
|
public StringView SelectedFile => _selectedFile;
|
||||||
|
|
||||||
|
char8[256] _newFileName = .();
|
||||||
|
bool _showNewFile = false;
|
||||||
|
AssetCreator _newFileCreator = null;
|
||||||
|
|
||||||
public this(EditorContentManager contentManager)
|
public this(EditorContentManager contentManager)
|
||||||
{
|
{
|
||||||
_manager = contentManager;
|
_manager = contentManager;
|
||||||
@@ -106,6 +113,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
bool alt_pressed = ImGui.GetIO().KeyAlt;
|
bool alt_pressed = ImGui.GetIO().KeyAlt;
|
||||||
|
|
||||||
|
// Table with two columns, one for Directory-Sidebar and one for File-Browser
|
||||||
if (ImGui.BeginTable("table", 2, .BordersInnerV | .Resizable | .Reorderable | .NoPadOuterX))
|
if (ImGui.BeginTable("table", 2, .BordersInnerV | .Resizable | .Reorderable | .NoPadOuterX))
|
||||||
{
|
{
|
||||||
if (alt_pressed)
|
if (alt_pressed)
|
||||||
@@ -178,6 +186,13 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
ShowCreateContextMenu(_creatorTree);
|
ShowCreateContextMenu(_creatorTree);
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
|
|
||||||
|
if (ImGui.MenuItem("Open C# Project..."))
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shows the menu for the given asset creator tree.
|
/// Shows the menu for the given asset creator tree.
|
||||||
@@ -187,7 +202,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
if (ImGui.MenuItem(subtree->Name.ToScopeCStr!()))
|
if (ImGui.MenuItem(subtree->Name.ToScopeCStr!()))
|
||||||
{
|
{
|
||||||
CreateAsset(subtree->Creator);
|
ShowNewFile(subtree->Creator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -204,8 +219,24 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shows a dummy file in the asset browser where the user can enter a file name and create an asset.
|
||||||
|
private void ShowNewFile(AssetCreator creator)
|
||||||
|
{
|
||||||
|
_newFileCreator = creator;
|
||||||
|
creator.DefaultFileName.CopyTo(_newFileName);
|
||||||
|
_showNewFile = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hides the dummy file.
|
||||||
|
private void HideNewFile()
|
||||||
|
{
|
||||||
|
_newFileCreator = null;
|
||||||
|
_showNewFile = false;
|
||||||
|
_newFileName = .();
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new asset with the given creator
|
/// Creates a new asset with the given creator
|
||||||
private void CreateAsset(AssetCreator creator)
|
private void CreateAsset()
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(_currentDirectory))
|
if (!Directory.Exists(_currentDirectory))
|
||||||
{
|
{
|
||||||
@@ -214,23 +245,29 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
|
|
||||||
String currentFile = scope String();
|
String currentFile = scope String();
|
||||||
Path.Combine(currentFile, _currentDirectory, creator.DefaultFileName);
|
Path.Combine(currentFile, _currentDirectory, StringView(&_newFileName));
|
||||||
|
|
||||||
String fileExtension = scope String();
|
|
||||||
Path.GetExtension(currentFile, fileExtension);
|
|
||||||
|
|
||||||
StringView fileWithoutExtension = currentFile[0...^(fileExtension.Length + 1)];
|
// Add file extension, if necessary
|
||||||
|
if (!currentFile.EndsWith(_newFileCreator.FileExtension))
|
||||||
|
{
|
||||||
|
currentFile.Append(_newFileCreator.FileExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringView fileWithoutExtension = currentFile[0...^(_newFileCreator.FileExtension.Length + 1)];
|
||||||
|
|
||||||
|
// If the file already exists find a unused number to attach to the end.
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (File.Exists(currentFile))
|
while (File.Exists(currentFile))
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
currentFile.Set(fileWithoutExtension);
|
currentFile.Set(fileWithoutExtension);
|
||||||
currentFile.AppendF($"({i})");
|
currentFile.AppendF($"({i})");
|
||||||
currentFile.Append(fileExtension);
|
currentFile.Append(_newFileCreator.FileExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
creator.CreateAsset(currentFile);
|
_newFileCreator.CreateAsset(currentFile);
|
||||||
|
|
||||||
|
HideNewFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Renders a sidebar that shows a tree of all directories in the asset folder.
|
/// Renders a sidebar that shows a tree of all directories in the asset folder.
|
||||||
@@ -367,6 +404,15 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_showNewFile)
|
||||||
|
{
|
||||||
|
ImGui.PushID("New File");
|
||||||
|
|
||||||
|
ShowNewFile();
|
||||||
|
|
||||||
|
ImGui.PopID();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float _zoom = 1.0f;
|
float _zoom = 1.0f;
|
||||||
@@ -600,6 +646,59 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.AttachTooltip(entry->Name);
|
ImGui.AttachTooltip(entry->Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Renders the button for the given directory item.
|
||||||
|
private void ShowNewFile()
|
||||||
|
{
|
||||||
|
ImGui.PushStyleVar(.WindowPadding, .(0, 0));
|
||||||
|
ImGui.PushStyleVar(.FramePadding, .(0, 0));
|
||||||
|
ImGui.PushStyleVar(.ItemSpacing, .(0, 0));
|
||||||
|
|
||||||
|
defer { ImGui.PopStyleVar(3); }
|
||||||
|
|
||||||
|
float2 DirectoryItemSize = IconSize + (float2)ImGui.GetStyle().WindowPadding * 2 + float2(0, ImGui.GetFontSize());
|
||||||
|
|
||||||
|
ImGui.BeginChild("item", (.)DirectoryItemSize, false, .NoScrollbar);
|
||||||
|
|
||||||
|
ImGui.PushStyleColor(.Button, ImGui.Vec4(0, 0, 0, 0));
|
||||||
|
|
||||||
|
// TODO: preview images
|
||||||
|
SubTexture2D image = s_FileTexture;
|
||||||
|
|
||||||
|
ImGui.ImageButton("FileImage", image, (.)IconSize);
|
||||||
|
|
||||||
|
ImGui.PopStyleColor();
|
||||||
|
|
||||||
|
ImGui.PushItemWidth((.)IconSize.X);
|
||||||
|
|
||||||
|
ImGui.InputText("##newFileNameBox", &_newFileName, _newFileName.Count - 1, .AutoSelectAll);
|
||||||
|
|
||||||
|
ImGui.PopItemWidth();
|
||||||
|
|
||||||
|
ImGui.SetKeyboardFocusHere(-1);
|
||||||
|
|
||||||
|
void CreateFile()
|
||||||
|
{
|
||||||
|
CreateAsset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.IsKeyDown(.Escape))
|
||||||
|
{
|
||||||
|
// Abort
|
||||||
|
HideNewFile();
|
||||||
|
}
|
||||||
|
else if (ImGui.IsItemDeactivatedAfterEdit())
|
||||||
|
{
|
||||||
|
CreateFile();
|
||||||
|
}
|
||||||
|
else if (ImGui.IsItemDeactivated())
|
||||||
|
{
|
||||||
|
// Abort
|
||||||
|
HideNewFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndChild();
|
||||||
|
}
|
||||||
|
|
||||||
private void DeleteItemPopup(TreeNode<AssetNode> fileOrFolder)
|
private void DeleteItemPopup(TreeNode<AssetNode> fileOrFolder)
|
||||||
{
|
{
|
||||||
// Always center this window when appearing
|
// Always center this window when appearing
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
private void RegisterAssetCreators()
|
private void RegisterAssetCreators()
|
||||||
{
|
{
|
||||||
Editor.Instance.ContentBrowserWindow.RegisterAssetCreator(new AssetCreator("Folder", "New Folder", new (path) =>
|
Editor.Instance.ContentBrowserWindow.RegisterAssetCreator(new AssetCreator("Folder", "New Folder", "", new (path) =>
|
||||||
{
|
{
|
||||||
if (Directory.CreateDirectory(path) case .Err(let error))
|
if (Directory.CreateDirectory(path) case .Err(let error))
|
||||||
{
|
{
|
||||||
@@ -152,7 +152,7 @@ namespace GlitchyEditor
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Editor.Instance.ContentBrowserWindow.RegisterAssetCreator(new AssetCreator("Scene", "New Scene.scene", new (path) =>
|
Editor.Instance.ContentBrowserWindow.RegisterAssetCreator(new AssetCreator("Scene", "New Scene", ".scene", new (path) =>
|
||||||
{
|
{
|
||||||
using (Scene newScene = CreateNewScene())
|
using (Scene newScene = CreateNewScene())
|
||||||
{
|
{
|
||||||
@@ -160,13 +160,104 @@ namespace GlitchyEditor
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Editor.Instance.ContentBrowserWindow.RegisterAssetCreator(new AssetCreator("Material", "New Material.mat", new (path) =>
|
Editor.Instance.ContentBrowserWindow.RegisterAssetCreator(new AssetCreator("Material", "New Material", ".mat", new (path) =>
|
||||||
{
|
{
|
||||||
using (Material newMaterial = new Material())
|
using (Material newMaterial = new Material())
|
||||||
{
|
{
|
||||||
_contentManager.SaveAssetToFile(newMaterial, path);
|
_contentManager.SaveAssetToFile(newMaterial, path);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
Editor.Instance.ContentBrowserWindow.RegisterAssetCreator(new AssetCreator("Script", "New Entity", ".cs", new (path) =>
|
||||||
|
{
|
||||||
|
String templatePath = scope .();
|
||||||
|
Directory.GetCurrentDirectory(templatePath);
|
||||||
|
Path.Combine(templatePath, "Resources/Templates/ScriptTemplate.cs");
|
||||||
|
|
||||||
|
String scriptContent = scope .();
|
||||||
|
|
||||||
|
if (File.ReadAllText(templatePath, scriptContent, true) case .Err(let error))
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Error($"Failed to read template file from \"{templatePath}\". Error: {error}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scriptContent.Replace("[ProjectName]", CurrentProject.Name);
|
||||||
|
|
||||||
|
String fileName = scope .();
|
||||||
|
Path.GetFileName(path, fileName);
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(fileName.EndsWith(".cs"));
|
||||||
|
|
||||||
|
if (fileName.EndsWith(".cs"))
|
||||||
|
fileName.RemoveFromEnd(3);
|
||||||
|
|
||||||
|
String pascalFileName = scope .(fileName.Length);
|
||||||
|
ToPascalCase(fileName, pascalFileName);
|
||||||
|
String cSharpClassName = scope .(pascalFileName.Length);
|
||||||
|
ToCSharpName(pascalFileName, cSharpClassName);
|
||||||
|
|
||||||
|
scriptContent.Replace("[EntityName]", cSharpClassName);
|
||||||
|
|
||||||
|
if (File.WriteAllText(path, scriptContent, false) case .Err)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Error($"Failed to save script file to \"{path}\".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToCSharpName(String input, String output)
|
||||||
|
{
|
||||||
|
for (char32 c in input.DecodedChars)
|
||||||
|
{
|
||||||
|
if (c.IsLetterOrDigit || c == '_' || c == '@')
|
||||||
|
{
|
||||||
|
output.Append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let decode = System.Text.UTF8.Decode(output.Ptr, output.Length);
|
||||||
|
|
||||||
|
// Make sure the name starts with a letter or _ or @
|
||||||
|
if (!(decode.c.IsLetter || decode.c == '_' || decode.c == '@'))
|
||||||
|
{
|
||||||
|
output.Insert(0, '@');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToPascalCase(String input, String output)
|
||||||
|
{
|
||||||
|
bool newWord = true;
|
||||||
|
|
||||||
|
for (char32 c in input.DecodedChars)
|
||||||
|
{
|
||||||
|
if (c.IsLetter)
|
||||||
|
{
|
||||||
|
if (newWord)
|
||||||
|
{
|
||||||
|
output.Append(c.ToUpper);
|
||||||
|
newWord = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output.Append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newWord = true;
|
||||||
|
|
||||||
|
if (c.IsWhiteSpace || c == '_')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output.Append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitGraphics()
|
private void InitGraphics()
|
||||||
|
|||||||
Reference in New Issue
Block a user