update forge
This commit is contained in:
@@ -17,6 +17,11 @@ namespace Gamesmiths.Forge.Godot.Editor.Statescript;
|
||||
internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISerializationListener
|
||||
{
|
||||
private const string ExpandedArraysMetaKey = "_expanded_arrays";
|
||||
private const string HeaderRowNodeName = "HeaderRow";
|
||||
private const string AddButtonNodeName = "AddButton";
|
||||
private const string VariablesScrollNodeName = "VariablesScroll";
|
||||
private const string VariableListNodeName = "VariableList";
|
||||
private const string VariableNameButtonMetaKey = "_variable_name_button";
|
||||
|
||||
private static readonly Color _variableColor = new(0xe5c07bff);
|
||||
private static readonly Color _highlightColor = new(0x56b6c2ff);
|
||||
@@ -64,7 +69,7 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
SizeFlagsVertical = SizeFlags.ExpandFill;
|
||||
CustomMinimumSize = new Vector2(360, 0);
|
||||
|
||||
var headerHBox = new HBoxContainer();
|
||||
var headerHBox = new HBoxContainer { Name = HeaderRowNodeName };
|
||||
AddChild(headerHBox);
|
||||
|
||||
var titleLabel = new Label
|
||||
@@ -77,6 +82,7 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
|
||||
_addButton = new Button
|
||||
{
|
||||
Name = AddButtonNodeName,
|
||||
Icon = _addIcon,
|
||||
Flat = true,
|
||||
TooltipText = "Add Variable",
|
||||
@@ -91,6 +97,7 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
|
||||
var scrollContainer = new ScrollContainer
|
||||
{
|
||||
Name = VariablesScrollNodeName,
|
||||
SizeFlagsVertical = SizeFlags.ExpandFill,
|
||||
SizeFlagsHorizontal = SizeFlags.ExpandFill,
|
||||
};
|
||||
@@ -99,6 +106,7 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
|
||||
_variableList = new VBoxContainer
|
||||
{
|
||||
Name = VariableListNodeName,
|
||||
SizeFlagsHorizontal = SizeFlags.ExpandFill,
|
||||
};
|
||||
|
||||
@@ -108,45 +116,19 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
public override void _ExitTree()
|
||||
{
|
||||
base._ExitTree();
|
||||
|
||||
if (_addButton is not null)
|
||||
{
|
||||
_addButton.Pressed -= OnAddPressed;
|
||||
}
|
||||
|
||||
_creationDialog?.QueueFree();
|
||||
_creationDialog = null;
|
||||
_newNameEdit = null;
|
||||
_newTypeDropdown = null;
|
||||
_newArrayToggle = null;
|
||||
ReleaseUiState();
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
if (_addButton is not null)
|
||||
{
|
||||
_addButton.Pressed -= OnAddPressed;
|
||||
}
|
||||
|
||||
if (_variableList is not null)
|
||||
{
|
||||
foreach (Node child in _variableList.GetChildren())
|
||||
{
|
||||
_variableList.RemoveChild(child);
|
||||
child.Free();
|
||||
}
|
||||
}
|
||||
|
||||
_creationDialog?.Free();
|
||||
_creationDialog = null;
|
||||
_newNameEdit = null;
|
||||
_newTypeDropdown = null;
|
||||
_newArrayToggle = null;
|
||||
ReleaseUiState();
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
if (_addButton is not null)
|
||||
EnsureControlsCached();
|
||||
|
||||
if (_addButton is not null && IsInstanceValid(_addButton))
|
||||
{
|
||||
_addButton.Pressed += OnAddPressed;
|
||||
}
|
||||
@@ -165,6 +147,31 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
RebuildList();
|
||||
}
|
||||
|
||||
public string? GetSelectedVariableName()
|
||||
{
|
||||
return _selectedVariableName;
|
||||
}
|
||||
|
||||
public void RestoreSelectedVariable(string? variableName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(variableName) || !HasVariableNamed(variableName))
|
||||
{
|
||||
_selectedVariableName = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectedVariableName = variableName;
|
||||
}
|
||||
|
||||
RefreshVariableSelectionVisuals();
|
||||
VariableHighlightChanged?.Invoke(_selectedVariableName);
|
||||
}
|
||||
|
||||
public void ClearSelectedVariable()
|
||||
{
|
||||
RestoreSelectedVariable(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="EditorUndoRedoManager"/> used for undo/redo support.
|
||||
/// </summary>
|
||||
@@ -179,26 +186,95 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
/// </summary>
|
||||
public void RebuildList()
|
||||
{
|
||||
EnsureControlsCached();
|
||||
|
||||
if (_variableList is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ClearVariableList();
|
||||
|
||||
if (_graph is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < _graph.Variables.Count; i++)
|
||||
{
|
||||
AddVariableRow(_graph.Variables[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
private static int FindTypeDropdownIndex(OptionButton dropdown, StatescriptVariableType variableType)
|
||||
{
|
||||
for (int i = 0; i < dropdown.ItemCount; i++)
|
||||
{
|
||||
if (dropdown.GetItemId(i) == (int)variableType)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static void UpdateVariableNameButtonAppearance(Button button, bool isSelected)
|
||||
{
|
||||
Color buttonColor = isSelected ? _highlightColor : _variableColor;
|
||||
button.AddThemeColorOverride("font_color", buttonColor);
|
||||
button.AddThemeColorOverride("font_pressed_color", _highlightColor);
|
||||
button.AddThemeColorOverride("font_hover_color", buttonColor.Lightened(0.2f));
|
||||
button.AddThemeColorOverride("font_hover_pressed_color", _highlightColor.Lightened(0.2f));
|
||||
}
|
||||
|
||||
private void EnsureControlsCached()
|
||||
{
|
||||
_addButton ??= GetNodeOrNull<Button>($"{HeaderRowNodeName}/{AddButtonNodeName}");
|
||||
_variableList ??= GetNodeOrNull<VBoxContainer>($"{VariablesScrollNodeName}/{VariableListNodeName}");
|
||||
}
|
||||
|
||||
private void ClearVariableList()
|
||||
{
|
||||
EnsureControlsCached();
|
||||
|
||||
if (_variableList is null || !IsInstanceValid(_variableList))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (Node child in _variableList.GetChildren())
|
||||
{
|
||||
_variableList.RemoveChild(child);
|
||||
child.Free();
|
||||
}
|
||||
}
|
||||
|
||||
if (_graph is null)
|
||||
private void ReleaseUiState()
|
||||
{
|
||||
if (_addButton is not null && IsInstanceValid(_addButton))
|
||||
{
|
||||
return;
|
||||
_addButton.Pressed -= OnAddPressed;
|
||||
}
|
||||
|
||||
for (var i = 0; i < _graph.Variables.Count; i++)
|
||||
ClearVariableList();
|
||||
|
||||
if (_creationDialog is not null && IsInstanceValid(_creationDialog))
|
||||
{
|
||||
AddVariableRow(_graph.Variables[i], i);
|
||||
if (_creationDialog is AcceptDialog acceptDialog)
|
||||
{
|
||||
acceptDialog.Confirmed -= OnCreationConfirmed;
|
||||
}
|
||||
|
||||
_creationDialog.Free();
|
||||
}
|
||||
|
||||
_creationDialog = null;
|
||||
_newNameEdit = null;
|
||||
_newTypeDropdown = null;
|
||||
_newArrayToggle = null;
|
||||
_variableList = null;
|
||||
_addButton = null;
|
||||
}
|
||||
|
||||
private void SaveExpandedArrayState()
|
||||
@@ -208,7 +284,7 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
return;
|
||||
}
|
||||
|
||||
var packed = new string[_expandedArrays.Count];
|
||||
string[] packed = new string[_expandedArrays.Count];
|
||||
_expandedArrays.CopyTo(packed);
|
||||
_graph.SetMeta(ExpandedArraysMetaKey, Variant.From(packed));
|
||||
}
|
||||
@@ -226,7 +302,7 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
|
||||
if (meta.VariantType == Variant.Type.PackedStringArray)
|
||||
{
|
||||
foreach (var name in meta.AsStringArray())
|
||||
foreach (string name in meta.AsStringArray())
|
||||
{
|
||||
_expandedArrays.Add(name);
|
||||
}
|
||||
@@ -254,7 +330,7 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
|
||||
rowContainer.AddChild(headerRow);
|
||||
|
||||
var isSelected = _selectedVariableName == variable.VariableName;
|
||||
bool isSelected = _selectedVariableName == variable.VariableName;
|
||||
|
||||
var nameButton = new Button
|
||||
{
|
||||
@@ -266,28 +342,15 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
Alignment = HorizontalAlignment.Left,
|
||||
};
|
||||
|
||||
Color buttonColor = isSelected ? _highlightColor : _variableColor;
|
||||
nameButton.AddThemeColorOverride("font_color", buttonColor);
|
||||
nameButton.AddThemeColorOverride("font_pressed_color", _highlightColor);
|
||||
nameButton.AddThemeColorOverride("font_hover_color", buttonColor.Lightened(0.2f));
|
||||
nameButton.AddThemeColorOverride("font_hover_pressed_color", _highlightColor.Lightened(0.2f));
|
||||
nameButton.SetMeta(VariableNameButtonMetaKey, variable.VariableName);
|
||||
UpdateVariableNameButtonAppearance(nameButton, isSelected);
|
||||
nameButton.AddThemeFontOverride(
|
||||
"font",
|
||||
EditorInterface.Singleton.GetEditorTheme().GetFont("bold", "EditorFonts"));
|
||||
|
||||
nameButton.Toggled += pressed =>
|
||||
{
|
||||
if (pressed)
|
||||
{
|
||||
_selectedVariableName = variable.VariableName;
|
||||
}
|
||||
else if (_selectedVariableName == variable.VariableName)
|
||||
{
|
||||
_selectedVariableName = null;
|
||||
}
|
||||
|
||||
RebuildList();
|
||||
VariableHighlightChanged?.Invoke(_selectedVariableName);
|
||||
SetSelectedVariable(variable.VariableName, pressed);
|
||||
};
|
||||
|
||||
headerRow.AddChild(nameButton);
|
||||
@@ -301,7 +364,7 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
typeLabel.AddThemeColorOverride("font_color", new Color(0.6f, 0.6f, 0.6f));
|
||||
headerRow.AddChild(typeLabel);
|
||||
|
||||
var capturedIndex = index;
|
||||
int capturedIndex = index;
|
||||
|
||||
var deleteButton = new Button
|
||||
{
|
||||
@@ -328,6 +391,47 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
rowContainer.AddChild(new HSeparator());
|
||||
}
|
||||
|
||||
private void SetSelectedVariable(string variableName, bool selected)
|
||||
{
|
||||
if (selected)
|
||||
{
|
||||
_selectedVariableName = variableName;
|
||||
}
|
||||
else if (_selectedVariableName == variableName)
|
||||
{
|
||||
_selectedVariableName = null;
|
||||
}
|
||||
|
||||
RefreshVariableSelectionVisuals();
|
||||
VariableHighlightChanged?.Invoke(_selectedVariableName);
|
||||
}
|
||||
|
||||
private void RefreshVariableSelectionVisuals()
|
||||
{
|
||||
if (_variableList is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshVariableSelectionVisualsRecursive(_variableList);
|
||||
}
|
||||
|
||||
private void RefreshVariableSelectionVisualsRecursive(Node parent)
|
||||
{
|
||||
foreach (Node child in parent.GetChildren())
|
||||
{
|
||||
if (child is Button button && button.HasMeta(VariableNameButtonMetaKey))
|
||||
{
|
||||
string variableName = button.GetMeta(VariableNameButtonMetaKey).AsString();
|
||||
bool isSelected = _selectedVariableName == variableName;
|
||||
button.SetPressedNoSignal(isSelected);
|
||||
UpdateVariableNameButtonAppearance(button, isSelected);
|
||||
}
|
||||
|
||||
RefreshVariableSelectionVisualsRecursive(child);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAddPressed()
|
||||
{
|
||||
if (_graph is null)
|
||||
@@ -373,12 +477,14 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
|
||||
StatescriptVariableType[] allTypes = StatescriptVariableTypeConverter.GetAllTypes();
|
||||
|
||||
for (var t = 0; t < allTypes.Length; t++)
|
||||
for (int t = 0; t < allTypes.Length; t++)
|
||||
{
|
||||
_newTypeDropdown.AddItem(StatescriptVariableTypeConverter.GetDisplayName(allTypes[t]), t);
|
||||
_newTypeDropdown.AddItem(
|
||||
StatescriptVariableTypeConverter.GetDisplayName(allTypes[t]),
|
||||
(int)allTypes[t]);
|
||||
}
|
||||
|
||||
_newTypeDropdown.Selected = (int)StatescriptVariableType.Int;
|
||||
_newTypeDropdown.Selected = FindTypeDropdownIndex(_newTypeDropdown, StatescriptVariableType.Int);
|
||||
typeRow.AddChild(_newTypeDropdown);
|
||||
|
||||
var arrayRow = new HBoxContainer { SizeFlagsHorizontal = SizeFlags.ExpandFill };
|
||||
@@ -404,20 +510,20 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
return;
|
||||
}
|
||||
|
||||
var name = _newNameEdit.Text.Trim();
|
||||
string name = _newNameEdit.Text.Trim();
|
||||
|
||||
if (string.IsNullOrEmpty(name) || HasVariableNamed(name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedIndex = _newTypeDropdown.Selected;
|
||||
int selectedIndex = _newTypeDropdown.Selected;
|
||||
if (selectedIndex < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedId = _newTypeDropdown.GetItemId(selectedIndex);
|
||||
int selectedId = _newTypeDropdown.GetItemId(selectedIndex);
|
||||
var varType = (StatescriptVariableType)selectedId;
|
||||
|
||||
var newVariable = new StatescriptGraphVariable
|
||||
@@ -431,8 +537,8 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
if (_undoRedo is not null)
|
||||
{
|
||||
_undoRedo.CreateAction("Add Graph Variable", customContext: _graph);
|
||||
_undoRedo.AddDoMethod(this, MethodName.DoAddVariable, _graph!, newVariable);
|
||||
_undoRedo.AddUndoMethod(this, MethodName.UndoAddVariable, _graph!, newVariable);
|
||||
_undoRedo.AddDoMethod(this, MethodName.DoAddVariable, _graph, newVariable);
|
||||
_undoRedo.AddUndoMethod(this, MethodName.UndoAddVariable, _graph, newVariable);
|
||||
_undoRedo.CommitAction();
|
||||
}
|
||||
else
|
||||
@@ -459,8 +565,8 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
if (_undoRedo is not null)
|
||||
{
|
||||
_undoRedo.CreateAction("Remove Graph Variable", customContext: _graph);
|
||||
_undoRedo.AddDoMethod(this, MethodName.DoRemoveVariable, _graph!, variable, index);
|
||||
_undoRedo.AddUndoMethod(this, MethodName.UndoRemoveVariable, _graph!, variable, index);
|
||||
_undoRedo.AddDoMethod(this, MethodName.DoRemoveVariable, _graph, variable, index);
|
||||
_undoRedo.AddUndoMethod(this, MethodName.UndoRemoveVariable, _graph, variable, index);
|
||||
_undoRedo.CommitAction();
|
||||
}
|
||||
else
|
||||
@@ -497,8 +603,8 @@ internal sealed partial class StatescriptVariablePanel : VBoxContainer, ISeriali
|
||||
}
|
||||
|
||||
const string baseName = "variable";
|
||||
var counter = 1;
|
||||
var name = baseName;
|
||||
int counter = 1;
|
||||
string name = baseName;
|
||||
|
||||
while (HasVariableNamed(name))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user