using System; using System.Linq; using UnityEditor.Toolbars; using UnityEngine; using UnityEngine.UIElements; namespace UnityEditor.Tilemaps { /// /// Popup Field for selecting the Active Palette for Grid Painting. /// [EditorToolbarElement(k_ToolbarId)] [UxmlElement] public sealed partial class TilePaletteActivePalettePopup : PopupField { internal const string k_ToolbarId = "Tools/Tile Palette Active Palette"; private static string kNullGameObjectName = L10n.Tr("Create New Tile Palette"); private static string kLabelTooltip = L10n.Tr("Specifies the currently active Palette used for painting in the Scene View."); /// /// USS class name of elements of this type. /// private new static readonly string ussClassName = "unity-tilepalette-activepalettes-field"; /// /// USS class name of labels in elements of this type. /// private new static readonly string labelUssClassName = ussClassName + "__label"; /// /// USS class name of input elements in elements of this type. /// private new static readonly string inputUssClassName = ussClassName + "__input"; private bool m_Active; /// /// Initializes and returns an instance of TilePaletteActivePalettesPopup. /// public TilePaletteActivePalettePopup() : this(null) {} /// /// Initializes and returns an instance of TilePaletteActivePalettesPopup. /// /// Label name for the Popup public TilePaletteActivePalettePopup(string label) : base(label, GridPaintingState.palettes.ToList(), GetActivePaletteIndex()) { AddToClassList(ussClassName); labelElement.AddToClassList(labelUssClassName); visualInput.AddToClassList(inputUssClassName); TilePaletteOverlayUtility.SetStyleSheet(this); labelElement.tooltip = kLabelTooltip; RegisterCallback(OnAttachedToPanel); RegisterCallback(OnDetachFromPanel); RegisterCallback(OnPointerDown); m_FormatSelectedValueCallback += FormatSelectedValueCallback; createMenuCallback += CreateMenuCallback; UpdateTargets(); SetValueWithoutNotify(GridPaintingState.palette); } private void OnAttachedToPanel(AttachToPanelEvent evt) { GridPaintingState.paletteChanged += OnPaletteChanged; GridPaintingState.palettesChanged += UpdateTargets; } private void OnDetachFromPanel(DetachFromPanelEvent evt) { GridPaintingState.palettesChanged += UpdateTargets; GridPaintingState.paletteChanged -= OnPaletteChanged; } private void OnPointerDown(PointerDownEvent evt) { m_Active = true; ShowMenu(); m_Active = false; } private void OnPaletteChanged(GameObject _) { UpdateActivePalette(); } private string FormatSelectedValueCallback(GameObject go) { if (go != null) return go.name; return kNullGameObjectName; } private AbstractGenericMenu CreateMenuCallback() { return new TilePaletteActivePaletteDropdownMenu(m_Active, Mathf.FloorToInt(this.resolvedStyle.width)); } private static int GetActivePaletteIndex() { return GridPaintingState.palettes.IndexOf(GridPaintingState.palette); } private void UpdateChoices() { choices.Clear(); foreach (var target in GridPaintingState.palettes) { choices.Add(target); } formatSelectedValueCallback = FormatSelectedValueCallback; } private void UpdateActivePalette() { var newIndex = GetActivePaletteIndex(); if (newIndex != -1 && choices.Count < newIndex) { UpdateChoices(); newIndex = GetActivePaletteIndex(); } index = newIndex; } private void UpdateTargets() { UpdateChoices(); UpdateActivePalette(); } } [EditorToolbarElement(k_ToolbarId)] internal class TilePaletteActivePalettePopupIcon : VisualElement { internal const string k_ToolbarId = "Tools/Tile Palette Active Palette Icon"; private static string kTooltip = L10n.Tr("Active Palette"); /// /// USS class name of elements of this type. /// public static readonly string ussClassName = "unity-tilepalette-activepalette-icon"; private readonly string k_IconPath = "Packages/com.unity.2d.tilemap/Editor/Icons/Tilemap.TilePalette.png"; public TilePaletteActivePalettePopupIcon() { AddToClassList(ussClassName); TilePaletteOverlayUtility.SetStyleSheet(this); style.backgroundImage = EditorGUIUtility.LoadIcon(k_IconPath); tooltip = kTooltip; } } [EditorToolbarElement(k_ToolbarId)] internal sealed class TilePaletteActivePaletteSyncToggle : EditorToolbarToggle { internal const string k_ToolbarId = "Tools/Tile Palette Active Palette Sync"; private static readonly string k_ToolSettingsClass = "unity-tool-settings"; private static readonly string k_ElementClass = "unity-tilepalette-activepalette-sync"; private static readonly string k_TooltipText = L10n.Tr("Sync Active Palette"); public Action ToggleChanged; public TilePaletteActivePaletteSyncToggle() { name = "Tile Palette Active Palette Sync"; AddToClassList(k_ToolSettingsClass); AddToClassList(k_ElementClass); TilePaletteOverlayUtility.SetStyleSheet(this); icon = EditorGUIUtility.LoadIcon("Linked"); tooltip = k_TooltipText; UpdateToggleState(); RegisterCallback(OnAttachedToPanel); RegisterCallback(OnDetachFromPanel); } private void OnAttachedToPanel(AttachToPanelEvent evt) { GridTargetBrushSync.instance.tilemapPaletteTargetsChanged += UpdateToggleState; GridPaintingState.scenePaintTargetChanged += OnScenePaintTargetChanged; GridPaintingState.paletteChanged += OnPaletteChanged; } private void OnDetachFromPanel(DetachFromPanelEvent evt) { GridTargetBrushSync.instance.tilemapPaletteTargetsChanged -= UpdateToggleState; GridPaintingState.scenePaintTargetChanged -= OnScenePaintTargetChanged; GridPaintingState.paletteChanged -= OnPaletteChanged; } private void OnScenePaintTargetChanged(GameObject target) { UpdateToggleState(); } private void OnPaletteChanged(GameObject palette) { UpdateToggleState(); } private void UpdateToggleState() { var sceneTarget = GridPaintingState.scenePaintTarget; var palette = GridPaintingState.palette; var hasTarget = GridTargetBrushSync.instance.HasTilemapPaletteTarget(sceneTarget, palette); SetValueWithoutNotify(hasTarget); } protected override void ToggleValue() { base.ToggleValue(); var sceneTarget = GridPaintingState.scenePaintTarget; var palette = GridPaintingState.palette; if (value) GridTargetBrushSync.instance.AddTilemapPaletteTarget(sceneTarget, palette); else GridTargetBrushSync.instance.RemoveTilemapPaletteTarget(sceneTarget, palette); UpdateToggleState(); ToggleChanged?.Invoke(value); } } }