using System;
using UnityEngine;
using UnityEngine.UIElements;
namespace UnityEditor.Tilemaps
{
///
/// A Visual Element which handles and displays a Tile Palette Clipboard.
/// A Tile Palette Clipboard shows the Active Palette for Grid Painting and allows
/// users to use the Active Brush to assign and pick items for painting.
///
[UxmlElement]
public partial class TilePaletteClipboardElement : VisualElement
{
///
/// Factory for TilePaletteClipboardElement.
///
[Obsolete("TilePaletteClipboardElementFactory is deprecated and will be removed. Use UxmlElementAttribute instead.", false)]
public class TilePaletteClipboardElementFactory : UxmlFactory {}
///
/// UxmlTraits for TilePaletteClipboardElement.
///
[Obsolete("TilePaletteClipboardElementUxmlTraits is deprecated and will be removed. Use UxmlElementAttribute instead.", false)]
public class TilePaletteClipboardElementUxmlTraits : UxmlTraits {}
private static readonly string ussClassName = "unity-tilepalette-clipboard-element";
private static readonly string k_Name = L10n.Tr("Tile Palette Clipboard Element");
private GridPaintPaletteClipboard m_TilePaletteClipboard;
private EditorWindow m_Window;
///
/// Callback when the active Brush does a Pick on the Clipboard.
///
public event Action onBrushPicked;
///
/// Whether the clipboard is unlocked for editing.
///
public bool clipboardUnlocked
{
get => m_TilePaletteClipboard.unlocked;
set => m_TilePaletteClipboard.unlocked = value;
}
///
/// The last active grid position on the clipboard.
///
public Vector3Int clipboardMouseGridPosition => new Vector3Int(m_TilePaletteClipboard.mouseGridPosition.x, m_TilePaletteClipboard.mouseGridPosition.y, m_TilePaletteClipboard.zPosition);
///
/// Callback when the clipboard unlock status has changed
///
public event Action clipboardUnlockedChanged;
internal GridPaintPaletteClipboard clipboardView => m_TilePaletteClipboard;
private TilePaletteClipboardFirstUserElement m_FirstUserElement;
private TilePaletteClipboardErrorElement m_ErrorElement;
private Image m_ClipboardImageElement;
private static readonly PrefColor tilePaletteBackgroundColor = new PrefColor("2D/Tile Palette Background"
, 1.0f / 255.0f // Light
, 35.0f / 255.0f
, 90.0f / 255.0f
, 127.0f / 255.0f
, 1.0f / 255.0f // Dark
, 35.0f / 255.0f
, 90.0f / 255.0f
, 127.0f / 255.0f);
///
/// Initializes and returns an instance of TilePaletteClipboardElement.
///
public TilePaletteClipboardElement()
{
AddToClassList(ussClassName);
name = k_Name;
TilePaletteOverlayUtility.SetStyleSheet(this);
RegisterCallback(OnAttachedToPanel);
RegisterCallback(OnDetachFromPanel);
m_ClipboardImageElement = new Image();
m_ClipboardImageElement.style.backgroundColor = tilePaletteBackgroundColor.Color;
m_ClipboardImageElement.focusable = true;
Add(m_ClipboardImageElement);
m_ErrorElement = new TilePaletteClipboardErrorElement();
m_ErrorElement.style.display = DisplayStyle.None;
m_ErrorElement.style.visibility = Visibility.Hidden;
m_ErrorElement.SetEmptyPaletteText();
Add(m_ErrorElement);
m_FirstUserElement = new TilePaletteClipboardFirstUserElement();
m_FirstUserElement.style.display = DisplayStyle.None;
m_FirstUserElement.style.visibility = Visibility.Hidden;
Add(m_FirstUserElement);
ScrollView ms = new ScrollView();
}
private void UnlockChanged(bool unlocked)
{
clipboardUnlockedChanged?.Invoke(unlocked);
}
private void OnAttachedToPanel(AttachToPanelEvent evt)
{
if (EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPlaying)
{
// Delay AttachToPanel if Editor is entering playmode
EditorApplication.delayCall += AttachToPanel;
}
else
{
AttachToPanel();
}
}
private void AttachToPanel()
{
if (m_TilePaletteClipboard == null)
{
m_TilePaletteClipboard = ScriptableObject.CreateInstance();
m_TilePaletteClipboard.hideFlags = HideFlags.HideAndDontSave;
m_TilePaletteClipboard.unlockedChanged += UnlockChanged;
m_TilePaletteClipboard.unlocked = false;
m_TilePaletteClipboard.attachedVisualElement = this;
var guiRect = new Rect(0, 0, layout.width, layout.height);
m_TilePaletteClipboard.guiRect = guiRect;
CheckPaletteState(m_TilePaletteClipboard.paletteInstance);
}
RegisterCallback(OnGeometryChangedEvent);
RegisterCallback(OnValidateCommandEvent);
RegisterCallback(OnExecuteCommandEvent);
RegisterCallback(OnWheelEvent);
RegisterCallback(OnPointerDownEvent);
RegisterCallback(OnPointerMoveEvent);
RegisterCallback(OnPointerUpEvent);
RegisterCallback(OnPointerEnterEvent);
RegisterCallback(OnPointerLeaveEvent);
m_ClipboardImageElement.RegisterCallback(OnKeyDownEvent);
m_ClipboardImageElement.RegisterCallback(OnKeyUpEvent);
RegisterCallback(OnDragEnterEvent);
RegisterCallback(OnDragUpdatedEvent);
RegisterCallback(OnDragPerformEvent);
RegisterCallback(OnDragLeaveEvent);
RegisterCallback(OnDragExitedEvent);
generateVisualContent += GenerateVisualContent;
GridPaintingState.beforePaletteChanged += BeforePaletteChanged;
GridPaintingState.paletteChanged += PaletteChanged;
}
private void GenerateVisualContent(MeshGenerationContext obj)
{
if (m_ClipboardImageElement.visible)
{
var texture = m_TilePaletteClipboard.RenderTexture();
EditorApplication.delayCall += () =>
{
m_ClipboardImageElement.image = texture;
};
}
}
private void OnDetachFromPanel(DetachFromPanelEvent evt)
{
UnregisterCallback(OnGeometryChangedEvent);
UnregisterCallback(OnValidateCommandEvent);
UnregisterCallback(OnExecuteCommandEvent);
UnregisterCallback(OnWheelEvent);
UnregisterCallback(OnPointerDownEvent);
UnregisterCallback(OnPointerMoveEvent);
UnregisterCallback(OnPointerUpEvent);
UnregisterCallback(OnPointerEnterEvent);
UnregisterCallback(OnPointerLeaveEvent);
m_ClipboardImageElement.UnregisterCallback(OnKeyDownEvent);
m_ClipboardImageElement.UnregisterCallback(OnKeyUpEvent);
UnregisterCallback(OnDragEnterEvent);
UnregisterCallback(OnDragUpdatedEvent);
UnregisterCallback(OnDragPerformEvent);
UnregisterCallback(OnDragExitedEvent);
UnregisterCallback(OnDragLeaveEvent);
generateVisualContent -= GenerateVisualContent;
if (m_TilePaletteClipboard != null)
m_TilePaletteClipboard.unlockedChanged -= UnlockChanged;
GridPaintingState.beforePaletteChanged -= BeforePaletteChanged;
GridPaintingState.paletteChanged -= PaletteChanged;
Cleanup();
}
private void OnGeometryChangedEvent(GeometryChangedEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
var guiRect = new Rect(0, 0, layout.width, layout.height);
m_TilePaletteClipboard.guiRect = guiRect;
m_ClipboardImageElement.image = m_TilePaletteClipboard.RenderTexture();
}
private void OnExecuteCommandEvent(ExecuteCommandEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.HandleExecuteCommandEvent(evt);
}
private void OnValidateCommandEvent(ValidateCommandEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.HandleValidateCommandEvent(evt);
}
private void OnWheelEvent(WheelEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.HandleWheelEvent(evt.delta, evt.mousePosition, evt.shiftKey);
evt.StopPropagation();
MarkDirtyRepaint();
}
private void OnPointerDownEvent(PointerDownEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.HandlePointerDownEvent(evt
, evt.button
, evt.altKey
, evt.ctrlKey
, evt.localPosition);
MarkDirtyRepaint();
}
private void OnPointerMoveEvent(PointerMoveEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.HandlePointerMoveEvent(evt
, evt.button
, evt.altKey
, evt.localPosition
, evt.deltaPosition);
MarkDirtyRepaint();
}
private void OnPointerUpEvent(PointerUpEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
if (onBrushPicked != null && m_TilePaletteClipboard != null)
m_TilePaletteClipboard.onBrushPicked += onBrushPicked;
m_TilePaletteClipboard.HandlePointerUpEvent(evt);
if (onBrushPicked != null && m_TilePaletteClipboard != null)
m_TilePaletteClipboard.onBrushPicked -= onBrushPicked;
MarkDirtyRepaint();
}
private void OnPointerEnterEvent(PointerEnterEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_ClipboardImageElement.Focus();
m_TilePaletteClipboard.HandlePointerEnterEvent(evt);
}
private void OnPointerLeaveEvent(PointerLeaveEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.HandlePointerLeaveEvent(evt);
}
private void OnKeyDownEvent(KeyDownEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.HandleKeyDownEvent(evt);
MarkDirtyRepaint();
}
private void OnKeyUpEvent(KeyUpEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.HandleKeyUpEvent();
MarkDirtyRepaint();
}
private void OnDragEnterEvent(DragEnterEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.HandleDragEnterEvent(evt);
CheckPaletteState(m_TilePaletteClipboard.paletteInstance);
}
private void OnDragUpdatedEvent(DragUpdatedEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.HandleDragUpdatedEvent(evt);
MarkDirtyRepaint();
}
private void OnDragPerformEvent(DragPerformEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.HandleDragPerformEvent(evt);
CheckPaletteState(m_TilePaletteClipboard.paletteInstance);
MarkDirtyRepaint();
}
private void OnDragLeaveEvent(DragLeaveEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.HandleDragLeaveEvent(evt);
CheckPaletteState(m_TilePaletteClipboard.paletteInstance);
MarkDirtyRepaint();
}
private void OnDragExitedEvent(DragExitedEvent evt)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.HandleDragExitedEvent(evt);
MarkDirtyRepaint();
}
///
/// Handles cleanup for the Tile Palette Clipboard.
///
private void Cleanup()
{
UnityEngine.Object.DestroyImmediate(m_TilePaletteClipboard);
m_TilePaletteClipboard = null;
}
private void BeforePaletteChanged()
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.OnBeforePaletteSelectionChanged();
}
private void PaletteChanged(GameObject palette)
{
if (m_TilePaletteClipboard == null)
return;
m_TilePaletteClipboard.OnAfterPaletteSelectionChanged();
CheckPaletteState(palette);
}
private void CheckPaletteState(GameObject palette)
{
if (palette == null && GridPaintingState.palettes.Count == 0)
{
m_ClipboardImageElement.style.display = DisplayStyle.None;
m_ClipboardImageElement.style.visibility = Visibility.Hidden;
m_ErrorElement.style.display = DisplayStyle.None;
m_ErrorElement.style.visibility = Visibility.Hidden;
m_ErrorElement.ClearText();
m_FirstUserElement.style.display = DisplayStyle.Flex;
m_FirstUserElement.style.visibility = Visibility.Visible;
}
else if (palette == null && GridPaintingState.palettes.Count > 0)
{
m_ClipboardImageElement.style.display = DisplayStyle.None;
m_ClipboardImageElement.style.visibility = Visibility.Hidden;
m_FirstUserElement.style.display = DisplayStyle.None;
m_FirstUserElement.style.visibility = Visibility.Hidden;
m_ErrorElement.style.display = DisplayStyle.Flex;
m_ErrorElement.style.visibility = Visibility.Visible;
m_ErrorElement.SetInvalidPaletteText();
}
else if (m_TilePaletteClipboard.activeDragAndDrop && m_TilePaletteClipboard.invalidDragAndDrop)
{
m_ClipboardImageElement.style.display = DisplayStyle.None;
m_ClipboardImageElement.style.visibility = Visibility.Hidden;
m_FirstUserElement.style.display = DisplayStyle.None;
m_FirstUserElement.style.visibility = Visibility.Hidden;
m_ErrorElement.style.display = DisplayStyle.Flex;
m_ErrorElement.style.visibility = Visibility.Visible;
m_ErrorElement.SetInvalidDragAndDropText();
}
else if (palette.GetComponent() == null)
{
m_ClipboardImageElement.style.display = DisplayStyle.None;
m_ClipboardImageElement.style.visibility = Visibility.Hidden;
m_FirstUserElement.style.display = DisplayStyle.None;
m_FirstUserElement.style.visibility = Visibility.Hidden;
m_ErrorElement.style.display = DisplayStyle.Flex;
m_ErrorElement.style.visibility = Visibility.Visible;
m_ErrorElement.SetInvalidGridText();
}
else if (m_TilePaletteClipboard.showNewEmptyClipboardInfo)
{
m_ClipboardImageElement.style.display = DisplayStyle.None;
m_ClipboardImageElement.style.visibility = Visibility.Hidden;
m_FirstUserElement.style.display = DisplayStyle.None;
m_FirstUserElement.style.visibility = Visibility.Hidden;
m_ErrorElement.style.display = DisplayStyle.Flex;
m_ErrorElement.style.visibility = Visibility.Visible;
m_ErrorElement.SetEmptyPaletteText();
}
else
{
m_ErrorElement.style.display = DisplayStyle.None;
m_ErrorElement.style.visibility = Visibility.Hidden;
m_ErrorElement.ClearText();
m_FirstUserElement.style.display = DisplayStyle.None;
m_FirstUserElement.style.visibility = Visibility.Hidden;
m_ClipboardImageElement.style.display = DisplayStyle.Flex;
m_ClipboardImageElement.style.visibility = Visibility.Visible;
}
if (m_Window != null)
m_Window.Repaint();
}
}
}