Skip to content

Commit

Permalink
prevent errors with YarnProjects created with Create Resource > YarnP…
Browse files Browse the repository at this point in the history
…roject, but warn the user to create a .yarnproject file instead. Option.cs does not need to derive from GodotObject, so make it a plain class. update samples to 4.2.1-stable
  • Loading branch information
dogboydog committed Dec 22, 2023
1 parent d4f1392 commit be6b068
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 41 deletions.
2 changes: 1 addition & 1 deletion YarnSpinner-Godot.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Godot.NET.Sdk/4.2.0">
<Project Sdk="Godot.NET.Sdk/4.2.1">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
Expand Down
145 changes: 107 additions & 38 deletions addons/YarnSpinner-Godot/Editor/YarnProjectInspectorPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ public partial class YarnProjectInspectorPlugin : EditorInspectorPlugin
private YarnProject _project;

private readonly PackedScene _fileNameLabelScene =
ResourceLoader.Load<PackedScene>("res://addons/YarnSpinner-Godot/Editor/UI/FilenameLabel.tscn");
ResourceLoader.Load<PackedScene>(
"res://addons/YarnSpinner-Godot/Editor/UI/FilenameLabel.tscn");

private readonly PackedScene _errorTextLabelScene =
ResourceLoader.Load<PackedScene>("res://addons/YarnSpinner-Godot/Editor/UI/ErrorTextLabel.tscn");
ResourceLoader.Load<PackedScene>(
"res://addons/YarnSpinner-Godot/Editor/UI/ErrorTextLabel.tscn");

private readonly PackedScene _contextLabelScene =
ResourceLoader.Load<PackedScene>("res://addons/YarnSpinner-Godot/Editor/UI/ContextLabel.tscn");
ResourceLoader.Load<PackedScene>(
"res://addons/YarnSpinner-Godot/Editor/UI/ContextLabel.tscn");

private VBoxContainer _errorContainer;
private RichTextLabel _sourceScriptsListLabel;
Expand All @@ -35,14 +38,20 @@ public override bool _CanHandle(GodotObject obj)
return obj is YarnProject;
}

public override bool _ParseProperty(GodotObject @object, Variant.Type type, string path,
public override bool _ParseProperty(GodotObject @object, Variant.Type type,
string path,
PropertyHint hint, string hintText, PropertyUsageFlags usage, bool wide)
{
if (@object is not YarnProject project)
{
return false;
}

if (IsTresYarnProject(project))
{
return true;
}

try
{
_project = project;
Expand Down Expand Up @@ -70,20 +79,23 @@ public override bool _ParseProperty(GodotObject @object, Variant.Type type, stri

if (path == nameof(YarnProject.ProjectErrors))
{
_compileErrorsPropertyEditor = new YarnCompileErrorsPropertyEditor();
_compileErrorsPropertyEditor =
new YarnCompileErrorsPropertyEditor();
AddPropertyEditor(path, _compileErrorsPropertyEditor);
_parseErrorControl = new ScrollContainer
{
SizeFlagsHorizontal = Control.SizeFlags.ExpandFill,
SizeFlagsVertical = Control.SizeFlags.ExpandFill,
};
int errorAreaHeight = 40;
if (_project.ProjectErrors != null && _project.ProjectErrors.Length > 0)
if (_project.ProjectErrors != null &&
_project.ProjectErrors.Length > 0)
{
errorAreaHeight = 200;
}

_parseErrorControl.CustomMinimumSize = new Vector2(0, errorAreaHeight);
_parseErrorControl.CustomMinimumSize =
new Vector2(0, errorAreaHeight);

_errorContainer = new VBoxContainer
{
Expand All @@ -92,7 +104,8 @@ public override bool _ParseProperty(GodotObject @object, Variant.Type type, stri
};
_parseErrorControl.AddChild(_errorContainer);
//parseErrorControl.BbcodeEnabled = true;
_compileErrorsPropertyEditor.OnErrorsUpdated += RenderCompilationErrors;
_compileErrorsPropertyEditor.OnErrorsUpdated +=
RenderCompilationErrors;
RenderCompilationErrors(_project);
AddCustomControl(_parseErrorControl);
return true;
Expand All @@ -102,7 +115,8 @@ public override bool _ParseProperty(GodotObject @object, Variant.Type type, stri
}
catch (Exception e)
{
GD.PushError($"Error in {nameof(YarnProjectInspectorPlugin)}: {e.Message}\n{e.StackTrace}");
GD.PushError(
$"Error in {nameof(YarnProjectInspectorPlugin)}: {e.Message}\n{e.StackTrace}");
return false;
}
}
Expand Down Expand Up @@ -135,7 +149,8 @@ public void CSVFileSelected(string savePath, string localeCode)
GD.Print($"CSV file selected for locale {localeCode}: {savePath}");
if (!_project.JSONProject.Localisation.ContainsKey(localeCode))
{
_project.JSONProject.Localisation.Add(localeCode, new Project.LocalizationInfo());
_project.JSONProject.Localisation.Add(localeCode,
new Project.LocalizationInfo());
}

_project.JSONProject.Localisation[localeCode].Strings = savePath;
Expand Down Expand Up @@ -164,13 +179,40 @@ public void LocaleAdded()
_project.NotifyPropertyListChanged();
}

/// <summary>
/// Returns true if the given project was created with Create Resource >
/// YarnProject rather than the tools menu.
/// As of 0.2.0, .yarnproject files should be created instead of creating
/// .tres files directly.
/// </summary>
private static bool IsTresYarnProject(YarnProject project) =>
string.IsNullOrWhiteSpace(project.JSONProjectPath)
|| project.ResourcePath.ToLowerInvariant().EndsWith(".tres");

public override void _ParseBegin(GodotObject @object)
{
try
{
_project = (YarnProject) @object;
if (IsTresYarnProject(_project))
{
AddCustomControl(new Label
{
Text =
"⚠ This YarnProject may have been created via Create Resource > YarnProject.\n" +
"Instead, create projects via Tools > YarnSpinner > Create Yarn Project.\n" +
"This will create a .yarnproject file that you can work with, rather than a .tres " +
"file.\n" +
"You should delete this .tres file.",
SizeFlagsHorizontal = Control.SizeFlags.ExpandFill,
AutowrapMode = TextServer.AutowrapMode.WordSmart,
});
return;
}

_project.JSONProject =
Yarn.Compiler.Project.LoadFromFile(ProjectSettings.GlobalizePath(_project.JSONProjectPath));
Yarn.Compiler.Project.LoadFromFile(
ProjectSettings.GlobalizePath(_project.JSONProjectPath));


var recompileButton = new Button();
Expand All @@ -189,7 +231,8 @@ public override void _ParseBegin(GodotObject @object)

var sourceScripts = _project.JSONProject.SourceFiles.ToList();
updateLocalizationsButton.Text = "Update Localizations";
updateLocalizationsButton.TooltipText = "Update Localization CSV and Godot .translation Files";
updateLocalizationsButton.TooltipText =
"Update Localization CSV and Godot .translation Files";
updateLocalizationsButton.Pressed += OnUpdateLocalizationsClicked;
AddCustomControl(updateLocalizationsButton);

Expand Down Expand Up @@ -218,25 +261,35 @@ public override void _ParseBegin(GodotObject @object)
}

_project.JSONProject.SourceFilePatterns =
_project.JSONProject.SourceFilePatterns.Where(existingPattern =>
!existingPattern.Equals(pattern));
_project.JSONProject.SourceFilePatterns.Where(
existingPattern =>
!existingPattern.Equals(pattern));
_project.SaveJSONProject();
YarnSpinnerPlugin.editorInterface.GetResourceFilesystem().ScanSources();
YarnSpinnerPlugin.editorInterface.GetResourceFilesystem()
.ScanSources();
_project.NotifyPropertyListChanged();
};
scriptPatternsGrid.AddChild(patternDeleteButton);
}

scriptPatternsGrid.AddChild(new Label {Text = "New Pattern",
TooltipText = "Add a pattern that will match .yarn scripts you want to include.\n" +
$"These patterns are relative to the directory in which this {YarnProject.YARN_PROJECT_EXTENSION} file is saved."});
scriptPatternsGrid.AddChild(new Label
{
Text = "New Pattern",
TooltipText =
"Add a pattern that will match .yarn scripts you want to include.\n" +
$"These patterns are relative to the directory in which this {YarnProject.YARN_PROJECT_EXTENSION} file is saved."
});
var scriptPatternInput = new LineEdit
{PlaceholderText = "**/*.yarn", SizeFlagsHorizontal = Control.SizeFlags.ExpandFill};
{
PlaceholderText = "**/*.yarn",
SizeFlagsHorizontal = Control.SizeFlags.ExpandFill
};
scriptPatternsGrid.AddChild(scriptPatternInput);
var addPatternButton = new Button {Text = "Add"};
addPatternButton.Pressed += () =>
{
if (!IsInstanceValid(_project) || !IsInstanceValid(scriptPatternInput))
if (!IsInstanceValid(_project) ||
!IsInstanceValid(scriptPatternInput))
{
return;
}
Expand All @@ -246,16 +299,20 @@ public override void _ParseBegin(GodotObject @object)
return;
}

if (_project.JSONProject.SourceFilePatterns.Contains(scriptPatternInput.Text))
if (_project.JSONProject.SourceFilePatterns.Contains(
scriptPatternInput.Text))
{
GD.Print($"Not adding duplicate pattern '{scriptPatternInput.Text}");
GD.Print(
$"Not adding duplicate pattern '{scriptPatternInput.Text}");
}
else
{
_project.JSONProject.SourceFilePatterns =
_project.JSONProject.SourceFilePatterns.Append(scriptPatternInput.Text);
_project.JSONProject.SourceFilePatterns.Append(
scriptPatternInput.Text);
_project.SaveJSONProject();
YarnSpinnerPlugin.editorInterface.GetResourceFilesystem().ScanSources();
YarnSpinnerPlugin.editorInterface.GetResourceFilesystem()
.ScanSources();
_project.NotifyPropertyListChanged();
}
};
Expand All @@ -266,7 +323,8 @@ public override void _ParseBegin(GodotObject @object)
var numScriptsText = "None";
if (sourceScripts.Any())
{
numScriptsText = $"{sourceScripts.Count} .yarn script{(sourceScripts.Count > 1 ? "s" : "")}";
numScriptsText =
$"{sourceScripts.Count} .yarn script{(sourceScripts.Count > 1 ? "s" : "")}";
}

var matchingScriptsHeader = new HBoxContainer
Expand All @@ -277,7 +335,8 @@ public override void _ParseBegin(GodotObject @object)
matchingScriptsHeader.AddChild(new Label {Text = "Matching Scripts"});
matchingScriptsHeader.AddChild(new Label
{
Text = numScriptsText, SizeFlagsHorizontal = Control.SizeFlags.ExpandFill,
Text = numScriptsText,
SizeFlagsHorizontal = Control.SizeFlags.ExpandFill,
HorizontalAlignment = HorizontalAlignment.Right
});
AddCustomControl(matchingScriptsHeader);
Expand All @@ -292,11 +351,13 @@ public override void _ParseBegin(GodotObject @object)
SizeFlagsHorizontal = Control.SizeFlags.ExpandFill,
SizeFlagsVertical = Control.SizeFlags.ExpandFill,
};
_sourceScriptsListLabel.CustomMinimumSize = new Vector2(0, scriptAreaHeight);
_sourceScriptsListLabel.CustomMinimumSize =
new Vector2(0, scriptAreaHeight);
RenderSourceScriptsList(_project);
AddCustomControl(_sourceScriptsListLabel);

var localeGrid = new GridContainer {SizeFlagsHorizontal = Control.SizeFlags.ExpandFill};
var localeGrid = new GridContainer
{SizeFlagsHorizontal = Control.SizeFlags.ExpandFill};
localeGrid.Columns = 3;

var label = new Label {Text = "Localization CSVs"};
Expand All @@ -309,7 +370,8 @@ public override void _ParseBegin(GodotObject @object)
};
var addButton = new Button {Text = "Add"};
SaveNewLocaleCode("", addButton);
textEntry.TextChanged += (string text) => SaveNewLocaleCode(text, addButton);
textEntry.TextChanged +=
(string text) => SaveNewLocaleCode(text, addButton);
localeGrid.AddChild(textEntry);

addButton.Pressed += LocaleAdded;
Expand Down Expand Up @@ -366,7 +428,8 @@ public override void _ParseBegin(GodotObject @object)
var changeBaseLocaleButton = new Button {Text = "Change"};
baseLocaleInput.TextChanged += (newText) =>
{
changeBaseLocaleButton.Disabled = string.IsNullOrWhiteSpace(newText);
changeBaseLocaleButton.Disabled =
string.IsNullOrWhiteSpace(newText);
};
changeBaseLocaleButton.Pressed += () =>
{
Expand All @@ -377,21 +440,24 @@ public override void _ParseBegin(GodotObject @object)

_project.JSONProject.BaseLanguage = baseLocaleInput.Text.Trim();
_project.JSONProject.SaveToFile(_project.JSONProject.Path);
YarnSpinnerPlugin.editorInterface.GetResourceFilesystem().ScanSources();
YarnSpinnerPlugin.editorInterface.GetResourceFilesystem()
.ScanSources();
};
baseLocaleRow.AddChild(changeBaseLocaleButton);
AddCustomControl(baseLocaleRow);
var writeBaseCSVButton = new Button();
writeBaseCSVButton.Text = "Export Strings and Metadata as CSV";
writeBaseCSVButton.TooltipText = "Write all of the lines in your Yarn Project to a CSV," +
" including the metadata, line IDs, and the names of the nodes" +
" in which each line appears.";
writeBaseCSVButton.TooltipText =
"Write all of the lines in your Yarn Project to a CSV," +
" including the metadata, line IDs, and the names of the nodes" +
" in which each line appears.";
writeBaseCSVButton.Pressed += OnBaseLanguageCSVClicked;
AddCustomControl(writeBaseCSVButton);
}
catch (Exception e)
{
GD.PushError($"Error in {nameof(YarnProjectInspectorPlugin)}: {e.Message}\n{e.StackTrace}");
GD.PushError(
$"Error in {nameof(YarnProjectInspectorPlugin)}: {e.Message}\n{e.StackTrace}");
}
}

Expand All @@ -401,7 +467,8 @@ private void OnBaseLanguageCSVClicked()
{
FileMode = FileDialog.FileModeEnum.SaveFile,
Access = FileDialog.AccessEnum.Filesystem,
Title = $"Select CSV Path for the base locale {_project.JSONProject.BaseLanguage}",
Title =
$"Select CSV Path for the base locale {_project.JSONProject.BaseLanguage}",
};
dialog.AddFilter("*.csv; CSV File");
dialog.FileSelected += OnBaseLanguageCSVFileSelected;
Expand Down Expand Up @@ -457,7 +524,8 @@ private void SetErrors(YarnProjectError[] errors)
{
var errorsInGroup = errorGroup.ToList();
var fileNameLabel = _fileNameLabelScene.Instantiate<Label>();
var resFileName = ProjectSettings.LocalizePath(errorsInGroup[0].FileName);
var resFileName =
ProjectSettings.LocalizePath(errorsInGroup[0].FileName);
fileNameLabel.Text = $"{resFileName}:";
_errorContainer.AddChild(fileNameLabel);
var separator = new HSeparator();
Expand All @@ -482,7 +550,8 @@ private void SetSourceScripts(IEnumerable<string> sourceScripts)
_sourceScriptsListLabel.Text = "";
foreach (var script in sourceScripts)
{
var resFileName = ProjectSettings.LocalizePath(script.Replace("\\", "/"));
var resFileName =
ProjectSettings.LocalizePath(script.Replace("\\", "/"));
_sourceScriptsListLabel.Text += resFileName + "\n";
}
}
Expand Down
2 changes: 1 addition & 1 deletion addons/YarnSpinner-Godot/Runtime/DialogueRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1377,7 +1377,7 @@ void ContinueDialogue()
}

/// <summary>
/// Called by a <see cref="DialogueViewBase"/> derived class from
/// Called by a <see cref="DialogueViewBase"/> implementing class from
/// <see cref="dialogueViews"/> to inform the <see
/// cref="DialogueRunner"/> that the user intents to proceed to the
/// next line.
Expand Down
2 changes: 1 addition & 1 deletion addons/YarnSpinner-Godot/Runtime/Option.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Godot;
using Yarn;

public partial class Option : GodotObject
public class Option
{
public int ID { get; private set; }
public string Text { get; private set; }
Expand Down

0 comments on commit be6b068

Please sign in to comment.