diff --git a/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs b/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs index 9844f3fda..1a308e08a 100644 --- a/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/ScriptsEditor.cs @@ -739,6 +739,8 @@ namespace FlaxEditor.CustomEditors.Dedicated /// public override void Initialize(LayoutElementsContainer layout) { + var style = FlaxEngine.GUI.Style.Current; + // Area for drag&drop scripts var dragArea = layout.CustomContainer(); dragArea.CustomControl.ScriptsEditor = this; @@ -800,17 +802,10 @@ namespace FlaxEditor.CustomEditors.Dedicated bool hasAllRequirements = true; if (scriptType.HasAttribute(typeof(RequireScriptAttribute), false)) { - RequireScriptAttribute scriptAttribute = null; - foreach (var e in scriptType.GetAttributes(false)) + var attribute = (RequireScriptAttribute)scriptType.GetAttributes(false).FirstOrDefault(x => x is RequireScriptAttribute); + if (attribute != null) { - if (e is not RequireScriptAttribute requireScriptAttribute) - continue; - scriptAttribute = requireScriptAttribute; - } - - if (scriptAttribute != null) - { - foreach (var type in scriptAttribute.RequiredTypes) + foreach (var type in attribute.RequiredTypes) { if (!type.IsSubclassOf(typeof(Script))) continue; @@ -825,15 +820,7 @@ namespace FlaxEditor.CustomEditors.Dedicated } if (scriptType.HasAttribute(typeof(RequireActorAttribute), false)) { - RequireActorAttribute attribute = null; - foreach (var e in scriptType.GetAttributes(false)) - { - if (e is not RequireActorAttribute requireActorAttribute) - continue; - attribute = requireActorAttribute; - break; - } - + var attribute = (RequireActorAttribute)scriptType.GetAttributes(false).FirstOrDefault(x => x is RequireActorAttribute); if (attribute != null) { var actor = script.Actor; @@ -850,7 +837,7 @@ namespace FlaxEditor.CustomEditors.Dedicated var title = Utilities.Utils.GetPropertyNameUI(scriptType.Name); var group = layout.Group(title, editor); if (!hasAllRequirements) - group.Panel.HeaderTextColor = FlaxEngine.GUI.Style.Current.Statusbar.Failed; + group.Panel.HeaderTextColor = style.Statusbar.Failed; if ((Presenter.Features & FeatureFlags.CacheExpandedGroups) != 0) { if (Editor.Instance.ProjectCache.IsGroupToggled(title)) @@ -863,9 +850,10 @@ namespace FlaxEditor.CustomEditors.Dedicated group.Panel.Open(); // Customize + float totalHeaderButtonsOffset = 0f; group.Panel.TooltipText = Editor.Instance.CodeDocs.GetTooltip(scriptType); if (script.HasPrefabLink) - group.Panel.HeaderTextColor = FlaxEngine.GUI.Style.Current.ProgressNormal; + group.Panel.HeaderTextColor = style.ProgressNormal; // Add toggle button to the group var headerHeight = group.Panel.HeaderHeight; @@ -889,7 +877,7 @@ namespace FlaxEditor.CustomEditors.Dedicated TooltipText = "Script reference.", AutoFocus = true, IsScrollable = false, - Color = FlaxEngine.GUI.Style.Current.ForegroundGrey, + Color = style.ForegroundGrey, Parent = group.Panel, Bounds = new Rectangle(scriptToggle.Right, 0.5f, headerHeight, headerHeight), Margin = new Margin(1), @@ -908,10 +896,35 @@ namespace FlaxEditor.CustomEditors.Dedicated var settingsButton = group.AddSettingsButton(); settingsButton.Tag = script; settingsButton.Clicked += OnSettingsButtonClicked; + totalHeaderButtonsOffset += settingsButton.Width + FlaxEditor.Utilities.Constants.UIMargin; + + // Add script obsolete icon to the group + if (scriptType.HasAttribute(typeof(ObsoleteAttribute), false)) + { + var attribute = (ObsoleteAttribute)scriptType.GetAttributes(false).First(x => x is ObsoleteAttribute); + var tooltip = "Script marked as obsolete." + + (string.IsNullOrEmpty(attribute.Message) ? "" : $"\n{attribute.Message}") + + (string.IsNullOrEmpty(attribute.DiagnosticId) ? "" : $"\n{attribute.DiagnosticId}"); + var obsoleteButton = group.AddHeaderButton(tooltip, totalHeaderButtonsOffset, Editor.Instance.Icons.Info32); + obsoleteButton.Color = Color.Orange; + obsoleteButton.MouseOverColor = Color.DarkOrange; + totalHeaderButtonsOffset += obsoleteButton.Width; + } + + // Show visual indicator if script only exists in prefab instance and is not part of the prefab + bool isPrefabActor = scripts.Any(s => s.Actor.HasPrefabLink); + if (isPrefabActor && script.PrefabID == Guid.Empty) + { + var prefabInstanceButton = group.AddHeaderButton("Script only exists in this prefab instance.", totalHeaderButtonsOffset, Editor.Instance.Icons.Add32); + prefabInstanceButton.Color = style.ProgressNormal; + prefabInstanceButton.MouseOverColor = style.ProgressNormal * 0.9f; + totalHeaderButtonsOffset += prefabInstanceButton.Width; + } // Adjust margin to not overlap with other ui elements in the header group.Panel.HeaderTextMargin = group.Panel.HeaderTextMargin with { Left = scriptDrag.Right - 12, Right = settingsButton.Width + Utilities.Constants.UIMargin }; group.Object(values, editor); + // Remove drop down arrows and containment lines if no objects in the group if (group.Children.Count == 0) { diff --git a/Source/Editor/CustomEditors/Elements/Container/GroupElement.cs b/Source/Editor/CustomEditors/Elements/Container/GroupElement.cs index 055c6a29d..a3397d10a 100644 --- a/Source/Editor/CustomEditors/Elements/Container/GroupElement.cs +++ b/Source/Editor/CustomEditors/Elements/Container/GroupElement.cs @@ -37,25 +37,35 @@ namespace FlaxEditor.CustomEditors.Elements public override ContainerControl ContainerControl => Panel; /// - /// Adds utility settings button to the group header. + /// Add utility settings button to the group header. /// /// The created control. public Image AddSettingsButton() + { + return AddHeaderButton("Settings", 0, Style.Current.Settings); + } + + /// + /// Adds a button to the group header. + /// + /// The created control. + public Image AddHeaderButton(string tooltipText, float xOffset, SpriteHandle sprite) { var style = Style.Current; + const float padding = 2.0f; var settingsButtonSize = Panel.HeaderHeight; Panel.HeaderTextMargin = Panel.HeaderTextMargin with { Right = settingsButtonSize + Utilities.Constants.UIMargin }; ; return new Image { - TooltipText = "Settings", + TooltipText = tooltipText, AutoFocus = true, AnchorPreset = AnchorPresets.TopRight, Parent = Panel, - Bounds = new Rectangle(Panel.Width - settingsButtonSize, 0, settingsButtonSize, settingsButtonSize), + Bounds = new Rectangle(Panel.Width - settingsButtonSize - xOffset, padding * 0.5f, settingsButtonSize - padding, settingsButtonSize - padding), IsScrollable = false, Color = style.ForegroundGrey, Margin = new Margin(1), - Brush = new SpriteBrush(style.Settings), + Brush = new SpriteBrush(sprite), }; } }