// Copyright © Gamesmiths Guild. #if TOOLS using System; using Gamesmiths.Forge.Godot.Resources.Statescript; using Godot; namespace Gamesmiths.Forge.Godot.Editor.Statescript; /// /// Base class for all Statescript property resolver editor controls. Extends so it can be /// added directly to the graph node UI and participates in the Godot scene tree (lifecycle, disposal, etc.). /// [Tool] internal abstract partial class NodeEditorProperty : PanelContainer { private Type[] _allowedExpectedTypes = []; /// /// Gets the display name shown in the resolver type dropdown (e.g., "Variable", "Constant", "Attribute"). /// public abstract string DisplayName { get; } /// /// Gets the resolver type identifier string used for matching against serialized resources. /// public abstract string ResolverTypeId { get; } /// /// Checks whether this resolver is compatible with the given expected type. /// /// The type expected by the node's input property. /// if this resolver can provide a value of the expected type. public abstract bool IsCompatibleWith(Type expectedType); /// /// Initializes the resolver editor UI. Called once after the control is created. /// /// The current graph resource (for accessing variables, etc.). /// The existing property binding to restore state from, or null for a new binding. /// The type expected by the node's input property. /// Callback invoked when the resolver configuration changes. /// Whether the input expects an array of values. public abstract void Setup( StatescriptGraph graph, StatescriptNodeProperty? property, Type expectedType, Action onChanged, bool isArray); /// /// Writes the current resolver configuration to the given property binding resource. /// /// The property binding to write to. public abstract void SaveTo(StatescriptNodeProperty property); /// /// Raised when the editor's layout size has changed (e.g. nested resolver swap, foldable toggle) so that the owning /// can call . /// public event Action? LayoutSizeChanged; /// /// Configures the concrete input types allowed for this editor when the surrounding context accepts more than one. /// /// The allowed expected types. public void ConfigureAllowedExpectedTypes(params Type[] allowedExpectedTypes) { _allowedExpectedTypes = allowedExpectedTypes; } /// /// Tries to provide a short inline summary for the current editor state when embedded in a collapsed foldout. /// /// The inline summary, when available. /// when an inline summary is available. public virtual bool TryGetInlineSummary(out string summary) { summary = string.Empty; return false; } /// /// Gets the preferred badge style for inline foldout summaries. /// public virtual InlineSummaryBadgeKind GetInlineSummaryBadgeKind() { return InlineSummaryBadgeKind.Resolver; } /// /// Tries to provide the graph-variable name represented by this editor or one of its nested editors for highlight /// propagation in folded summaries. /// /// The variable name, when available. public virtual bool TryGetHighlightedVariableName(out string variableName) { variableName = string.Empty; return false; } /// /// Tries to provide the shared-variable identity represented by this editor or one of its nested editors for /// highlight propagation in folded summaries. /// /// The shared-variable set path, when available. /// The shared variable name, when available. public virtual bool TryGetHighlightedSharedVariable(out string sharedVariableSetPath, out string variableName) { sharedVariableSetPath = string.Empty; variableName = string.Empty; return false; } /// /// Clears all delegate fields to prevent serialization issues during hot-reload. Called before the editor is /// serialized or freed. /// public virtual void ClearCallbacks() { LayoutSizeChanged = null; } /// /// Notifies listeners that the editor layout has changed size. /// protected void RaiseLayoutSizeChanged() { LayoutSizeChanged?.Invoke(); } protected Type[] GetAllowedExpectedTypes(Type fallbackExpectedType) { return _allowedExpectedTypes.Length > 0 ? _allowedExpectedTypes : [fallbackExpectedType]; } } #endif