update forge
This commit is contained in:
@@ -11,7 +11,10 @@ public partial class AttributeEditorProperty : EditorProperty, ISerializationLis
|
||||
private const int ButtonSize = 26;
|
||||
private const int PopupSize = 300;
|
||||
|
||||
private Label _label = null!;
|
||||
private Label? _label;
|
||||
private Button? _button;
|
||||
private Popup? _popup;
|
||||
private Tree? _tree;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
@@ -19,20 +22,20 @@ public partial class AttributeEditorProperty : EditorProperty, ISerializationLis
|
||||
|
||||
var hBox = new HBoxContainer();
|
||||
_label = new Label { Text = "None", SizeFlagsHorizontal = SizeFlags.ExpandFill };
|
||||
var button = new Button { Icon = dropdownIcon, CustomMinimumSize = new Vector2(ButtonSize, 0) };
|
||||
_button = new Button { Icon = dropdownIcon, CustomMinimumSize = new Vector2(ButtonSize, 0) };
|
||||
|
||||
hBox.AddChild(_label);
|
||||
hBox.AddChild(button);
|
||||
hBox.AddChild(_button);
|
||||
AddChild(hBox);
|
||||
|
||||
var popup = new Popup { Size = new Vector2I(PopupSize, PopupSize) };
|
||||
var tree = new Tree
|
||||
_popup = new Popup { Size = new Vector2I(PopupSize, PopupSize) };
|
||||
_tree = new Tree
|
||||
{
|
||||
HideRoot = true,
|
||||
AnchorRight = 1,
|
||||
AnchorBottom = 1,
|
||||
};
|
||||
popup.AddChild(tree);
|
||||
_popup.AddChild(_tree);
|
||||
|
||||
var bg = new StyleBoxFlat
|
||||
{
|
||||
@@ -40,74 +43,125 @@ public partial class AttributeEditorProperty : EditorProperty, ISerializationLis
|
||||
.GetEditorTheme()
|
||||
.GetColor("dark_color_2", "Editor"),
|
||||
};
|
||||
tree.AddThemeStyleboxOverride("panel", bg);
|
||||
_tree.AddThemeStyleboxOverride("panel", bg);
|
||||
|
||||
AddChild(popup);
|
||||
AddChild(_popup);
|
||||
|
||||
BuildAttributeTree(tree);
|
||||
BuildAttributeTree(_tree);
|
||||
|
||||
button.Pressed += () =>
|
||||
{
|
||||
Window win = GetWindow();
|
||||
popup.Position = (Vector2I)button.GlobalPosition
|
||||
+ win.Position
|
||||
- new Vector2I(PopupSize - ButtonSize, -30);
|
||||
popup.Popup();
|
||||
};
|
||||
|
||||
tree.ItemActivated += () =>
|
||||
{
|
||||
TreeItem item = tree.GetSelected();
|
||||
if (item?.HasMeta("attribute_path") != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var fullPath = item.GetMeta("attribute_path").AsString();
|
||||
_label.Text = fullPath;
|
||||
EmitChanged(GetEditedProperty(), fullPath);
|
||||
popup.Hide();
|
||||
};
|
||||
_button.Pressed += OnButtonPressed;
|
||||
_tree.ItemActivated += OnTreeItemActivated;
|
||||
}
|
||||
|
||||
public override void _UpdateProperty()
|
||||
{
|
||||
var value = GetEditedObject().Get(GetEditedProperty()).AsString();
|
||||
if (_label is null || !IsInstanceValid(_label))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string value = GetEditedObject().Get(GetEditedProperty()).AsString();
|
||||
_label.Text = string.IsNullOrEmpty(value) ? "None" : value;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
ReleaseUiState();
|
||||
FreeAllChildren();
|
||||
base._ExitTree();
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
for (var i = GetChildCount() - 1; i >= 0; i--)
|
||||
{
|
||||
Node child = GetChild(i);
|
||||
RemoveChild(child);
|
||||
child.Free();
|
||||
}
|
||||
ReleaseUiState();
|
||||
FreeAllChildren();
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
// This method was intentionally left blank.
|
||||
}
|
||||
|
||||
private static void BuildAttributeTree(Tree tree)
|
||||
{
|
||||
TreeItem root = tree.CreateItem();
|
||||
|
||||
foreach (var attributeSet in EditorUtils.GetAttributeSetOptions())
|
||||
foreach (string attributeSet in EditorUtils.GetAttributeSetOptions())
|
||||
{
|
||||
TreeItem setItem = tree.CreateItem(root);
|
||||
setItem.SetText(0, attributeSet);
|
||||
setItem.Collapsed = true;
|
||||
|
||||
foreach (var attribute in EditorUtils.GetAttributeOptions(attributeSet))
|
||||
foreach (string attribute in EditorUtils.GetAttributeOptions(attributeSet))
|
||||
{
|
||||
TreeItem attributeItem = tree.CreateItem(setItem);
|
||||
var attributePath = $"{attributeSet}.{attribute}";
|
||||
string attributePath = $"{attributeSet}.{attribute}";
|
||||
attributeItem.SetText(0, attribute);
|
||||
attributeItem.SetMeta("attribute_path", attributePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnButtonPressed()
|
||||
{
|
||||
if (_button is null || _popup is null || !IsInstanceValid(_button) || !IsInstanceValid(_popup))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Window win = GetWindow();
|
||||
_popup.Position = (Vector2I)_button.GlobalPosition
|
||||
+ win.Position
|
||||
- new Vector2I(PopupSize - ButtonSize, -30);
|
||||
_popup.Popup();
|
||||
}
|
||||
|
||||
private void OnTreeItemActivated()
|
||||
{
|
||||
if (_tree is null || _popup is null || _label is null
|
||||
|| !IsInstanceValid(_tree) || !IsInstanceValid(_popup) || !IsInstanceValid(_label))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TreeItem item = _tree.GetSelected();
|
||||
if (item?.HasMeta("attribute_path") != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string fullPath = item.GetMeta("attribute_path").AsString();
|
||||
_label.Text = fullPath;
|
||||
EmitChanged(GetEditedProperty(), fullPath);
|
||||
_popup.Hide();
|
||||
}
|
||||
|
||||
private void ReleaseUiState()
|
||||
{
|
||||
if (_button is not null && IsInstanceValid(_button))
|
||||
{
|
||||
_button.Pressed -= OnButtonPressed;
|
||||
}
|
||||
|
||||
if (_tree is not null && IsInstanceValid(_tree))
|
||||
{
|
||||
_tree.ItemActivated -= OnTreeItemActivated;
|
||||
}
|
||||
|
||||
_label = null;
|
||||
_button = null;
|
||||
_popup = null;
|
||||
_tree = null;
|
||||
}
|
||||
|
||||
private void FreeAllChildren()
|
||||
{
|
||||
for (int i = GetChildCount() - 1; i >= 0; i--)
|
||||
{
|
||||
Node child = GetChild(i);
|
||||
RemoveChild(child);
|
||||
child.Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Gamesmiths.Forge.Godot.Editor.Attributes;
|
||||
[Tool]
|
||||
public partial class AttributeSetClassEditorProperty : EditorProperty, ISerializationListener
|
||||
{
|
||||
private OptionButton _optionButton = null!;
|
||||
private OptionButton? _optionButton;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
@@ -22,60 +22,25 @@ public partial class AttributeSetClassEditorProperty : EditorProperty, ISerializ
|
||||
AddChild(_optionButton);
|
||||
|
||||
_optionButton.AddItem("Select AttributeSet Class");
|
||||
foreach (var option in EditorUtils.GetAttributeSetOptions())
|
||||
foreach (string option in EditorUtils.GetAttributeSetOptions())
|
||||
{
|
||||
_optionButton.AddItem(option);
|
||||
}
|
||||
|
||||
_optionButton.ItemSelected += x =>
|
||||
{
|
||||
var className = _optionButton.GetItemText((int)x);
|
||||
EmitChanged(GetEditedProperty(), className);
|
||||
|
||||
GodotObject @object = GetEditedObject();
|
||||
if (@object is not null)
|
||||
{
|
||||
var dictionary = new Dictionary<string, AttributeValues>();
|
||||
|
||||
var assembly = Assembly.GetAssembly(typeof(ForgeAttributeSet));
|
||||
Type? targetType = System.Array.Find(assembly?.GetTypes() ?? [], x => x.Name == className);
|
||||
if (targetType is not null)
|
||||
{
|
||||
System.Collections.Generic.IEnumerable<PropertyInfo> attributeProperties = targetType
|
||||
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
.Where(x => x.PropertyType == typeof(EntityAttribute));
|
||||
|
||||
foreach (var propertyName in attributeProperties.Select(x => x.Name))
|
||||
{
|
||||
if (@object is not ForgeAttributeSet forgeAttributeSet)
|
||||
{
|
||||
dictionary[propertyName] = new AttributeValues(0, 0, int.MaxValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
AttributeSet? attributeSet = forgeAttributeSet.GetAttributeSet();
|
||||
if (attributeSet is null)
|
||||
{
|
||||
dictionary[propertyName] = new AttributeValues(0, 0, int.MaxValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
EntityAttribute key = attributeSet.AttributesMap[className + "." + propertyName];
|
||||
dictionary[propertyName] = new AttributeValues(key.CurrentValue, key.Min, key.Max);
|
||||
}
|
||||
}
|
||||
|
||||
EmitChanged("InitialAttributeValues", dictionary);
|
||||
}
|
||||
};
|
||||
_optionButton.ItemSelected += OnItemSelected;
|
||||
}
|
||||
|
||||
public override void _UpdateProperty()
|
||||
{
|
||||
if (_optionButton is null || !IsInstanceValid(_optionButton))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GodotObject obj = GetEditedObject();
|
||||
StringName property = GetEditedProperty();
|
||||
var val = obj.Get(property).AsString();
|
||||
for (var i = 0; i < _optionButton.GetItemCount(); i++)
|
||||
string val = obj.Get(property).AsString();
|
||||
for (int i = 0; i < _optionButton.GetItemCount(); i++)
|
||||
{
|
||||
if (_optionButton.GetItemText(i) == val)
|
||||
{
|
||||
@@ -85,18 +50,90 @@ public partial class AttributeSetClassEditorProperty : EditorProperty, ISerializ
|
||||
}
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
ReleaseUiState();
|
||||
FreeAllChildren();
|
||||
base._ExitTree();
|
||||
}
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
for (var i = GetChildCount() - 1; i >= 0; i--)
|
||||
ReleaseUiState();
|
||||
FreeAllChildren();
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
|
||||
private void OnItemSelected(long index)
|
||||
{
|
||||
if (_optionButton is null || !IsInstanceValid(_optionButton))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string className = _optionButton.GetItemText((int)index);
|
||||
EmitChanged(GetEditedProperty(), className);
|
||||
|
||||
GodotObject @object = GetEditedObject();
|
||||
if (@object is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var dictionary = new Dictionary<string, AttributeValues>();
|
||||
|
||||
var assembly = Assembly.GetAssembly(typeof(ForgeAttributeSet));
|
||||
Type? targetType = System.Array.Find(assembly?.GetTypes() ?? [], x => x.Name == className);
|
||||
if (targetType is not null)
|
||||
{
|
||||
System.Collections.Generic.IEnumerable<PropertyInfo> attributeProperties = targetType
|
||||
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
.Where(x => x.PropertyType == typeof(EntityAttribute));
|
||||
|
||||
foreach (string? propertyName in attributeProperties.Select(x => x.Name))
|
||||
{
|
||||
if (@object is not ForgeAttributeSet forgeAttributeSet)
|
||||
{
|
||||
dictionary[propertyName] = new AttributeValues(0, 0, int.MaxValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
AttributeSet? attributeSet = forgeAttributeSet.GetAttributeSet();
|
||||
if (attributeSet is null)
|
||||
{
|
||||
dictionary[propertyName] = new AttributeValues(0, 0, int.MaxValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
EntityAttribute key = attributeSet.AttributesMap[className + "." + propertyName];
|
||||
dictionary[propertyName] = new AttributeValues(key.CurrentValue, key.Min, key.Max);
|
||||
}
|
||||
}
|
||||
|
||||
EmitChanged("InitialAttributeValues", dictionary);
|
||||
}
|
||||
|
||||
private void ReleaseUiState()
|
||||
{
|
||||
if (_optionButton is not null && IsInstanceValid(_optionButton))
|
||||
{
|
||||
_optionButton.ItemSelected -= OnItemSelected;
|
||||
}
|
||||
|
||||
_optionButton = null;
|
||||
}
|
||||
|
||||
private void FreeAllChildren()
|
||||
{
|
||||
for (int i = GetChildCount() - 1; i >= 0; i--)
|
||||
{
|
||||
Node child = GetChild(i);
|
||||
RemoveChild(child);
|
||||
child.Free();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -40,7 +40,7 @@ public partial class AttributeSetValuesEditorProperty : EditorProperty, ISeriali
|
||||
return;
|
||||
}
|
||||
|
||||
var className = obj.AttributeSetClass;
|
||||
string className = obj.AttributeSetClass;
|
||||
var assembly = Assembly.GetAssembly(typeof(ForgeAttributeSet));
|
||||
Type? targetType = System.Array.Find(assembly?.GetTypes() ?? [], x => x.Name == className);
|
||||
|
||||
@@ -53,7 +53,7 @@ public partial class AttributeSetValuesEditorProperty : EditorProperty, ISeriali
|
||||
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
.Where(x => x.PropertyType == typeof(EntityAttribute));
|
||||
|
||||
foreach (var attributeName in attributeProperties.Select(x => x.Name))
|
||||
foreach (string? attributeName in attributeProperties.Select(x => x.Name))
|
||||
{
|
||||
var groupVBox = new VBoxContainer();
|
||||
|
||||
@@ -99,7 +99,7 @@ public partial class AttributeSetValuesEditorProperty : EditorProperty, ISeriali
|
||||
VBoxContainer? attributesRoot = GetNodeOrNull<VBoxContainer>("AttributesRoot");
|
||||
if (attributesRoot is not null)
|
||||
{
|
||||
for (var i = attributesRoot.GetChildCount() - 1; i >= 0; i--)
|
||||
for (int i = attributesRoot.GetChildCount() - 1; i >= 0; i--)
|
||||
{
|
||||
Node child = attributesRoot.GetChild(i);
|
||||
attributesRoot.RemoveChild(child);
|
||||
@@ -169,7 +169,7 @@ public partial class AttributeSetValuesEditorProperty : EditorProperty, ISeriali
|
||||
|
||||
private static void FreeAllChildren(Node node)
|
||||
{
|
||||
for (var i = node.GetChildCount() - 1; i >= 0; i--)
|
||||
for (int i = node.GetChildCount() - 1; i >= 0; i--)
|
||||
{
|
||||
node.GetChild(i).QueueFree();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user