Game.UI.Editor.EditorPanelUISystem
Assembly: Game
Namespace: Game.UI.Editor
Type: class
Base: UISystemBase
Summary:
Manages the in-game editor inspector panel UI. Tracks the currently active IEditorPanel, synchronizes UI bindings (active state, title, width, widget list, and widget renderer), forwards widget value changes to the active panel, and enables/disables underlying ComponentSystemBase implementations for panels when switching. Designed to operate in both Game and Editor modes (GameMode.GameOrEditor). Sets up common widget bindings used by editor inspector UIs.
Fields
-
private IEditorPanel m_LastPanel
Tracks the previously active editor panel. Used to disable and update the previous panel's ComponentSystemBase (if the panel implements ComponentSystemBase) when switching panels. -
private ValueBinding<bool> m_ActiveBinding
Binding for the editor panel "active" flag ("editorPanel", "active"). Updated each frame to reflect whether an editor panel is active. -
private ValueBinding<LocalizedString?> m_TitleBinding
Binding for the editor panel title ("editorPanel", "title"). Holds a nullable LocalizedString and is updated to the active panel's title when present. -
private WidgetBindings m_WidgetBindings
Holds bindings for the child widgets of the active editor panel ("editorPanel"). Its children are set to activePanel.children each update; it also raises EventValueChanged which is handled by this system to forward widget changes.
Properties
-
public override GameMode gameMode { get; }
Returns GameMode.GameOrEditor, indicating the system runs in both regular game and editor contexts. -
[CanBeNull] public IEditorPanel activePanel { get; set; }
The currently active editor panel. Can be set by other code to open or close an inspector. When set to a different panel, OnUpdate will enable/disable underlying ComponentSystemBase implementations as needed. -
private EditorPanelWidgetRenderer widgetRenderer { get; }
Read-only helper property that returns the widget renderer for the active panel (activePanel.widgetRenderer) or EditorPanelWidgetRenderer.Editor when no panel is active. Used to publish the renderer type to bindings.
Constructors
public EditorPanelUISystem()
Default constructor. Marked with [Preserve] to avoid stripping. Initialization of runtime state is handled in OnCreate.
Methods
protected override void OnCreate()
Initializes bindings and widget bindings for the editor panel UI:- Adds a boolean binding for "editorPanel/active".
- Adds a nullable LocalizedString binding for "editorPanel/title".
- Adds update bindings for "editorPanel/width" (via GetWidth) and "editorPanel/widgetRenderer".
- Constructs WidgetBindings ("editorPanel"), registers common editor widget bindings via AddEditorWidgetBindings, and subscribes to its EventValueChanged to call OnValueChanged.
-
Adds trigger bindings: "editorPanel/cancel" -> Cancel, "editorPanel/close" -> Close, and "editorPanel/setWidth" -> SetWidth.
-
public static void AddEditorWidgetBindings(WidgetBindings widgetBindings)
Registers standard and editor-specific widget binding types with the provided WidgetBindings instance. Includes default bindings and bindings for: -
EditorSection, SeasonsField, IItemPicker, PopupSearchField, AnimationCurveField, LocalizationField, FilterMenu, HierarchyMenu, ExternalLinkField, ListField. This centralizes binding registration so all editor inspector panels use the same widget behaviors.
-
protected override void OnGameLoaded(Context serializationContext)
Called after game data is loaded; resets activePanel to null to ensure no stale panel remains active across loads. -
protected override void OnUpdate()
Core update loop for the UI system: - Detects when activePanel has changed. If the previous panel implemented ComponentSystemBase, it is disabled and updated once. The new panel (if a ComponentSystemBase) is enabled.
- If activePanel is present, updates its ComponentSystemBase (if any), sets m_ActiveBinding to true, updates the title binding, and assigns activePanel.children to m_WidgetBindings.children.
- If no activePanel, clears bindings (active false, null title) and sets m_WidgetBindings.children to an empty array.
-
Calls base.OnUpdate at the end.
-
public void OnValueChanged(IWidget widget)
Forwarder that calls activePanel?.OnValueChanged(widget). Invoked by m_WidgetBindings.EventValueChanged when a widget's value changes. -
private int GetWidth()
Returns the inspector width to publish to the UI: uses SharedSettings.instance?.editor?.inspectorWidth with a fallback default of 450. -
private void SetWidth(int width)
Updates SharedSettings.instance.editor.inspectorWidth if settings exist. Invoked by the "editorPanel/setWidth" trigger binding. -
private void Cancel()
Invokes activePanel.OnCancel(); if that returns true (meaning the panel accepted the cancellation), clears activePanel (closes it). -
private void Close()
Invokes activePanel.OnClose(); if that returns true (meaning the panel agreed to close), clears activePanel.
Usage Example
// Example: open a custom editor panel instance from some other system or UI command
var inspectorSystem = World.DefaultGameObjectInjectionWorld?.GetExistingSystemManaged<EditorPanelUISystem>();
if (inspectorSystem != null)
{
// myPanel implements IEditorPanel (and optionally ComponentSystemBase)
inspectorSystem.activePanel = myPanel;
}
// The EditorPanelUISystem will:
// - enable myPanel if it is a ComponentSystemBase,
// - publish its title and widgets to the UI,
// - forward widget changes to myPanel.OnValueChanged,
// - and handle cancel/close triggers that call myPanel.OnCancel/OnClose.
Additional notes: - The system uses WidgetBindings to centralize widget handling; call AddEditorWidgetBindings when creating other inspector-like widget bindings to ensure consistent widget behavior. - The system relies on SharedSettings for persistent inspector width; mods can update SharedSettings.instance.editor.inspectorWidth to change the default width.