csharp/365082218/meteor_original_ios/Assets/ThirdParty/RnM%20UI%202%20for%20UGUI/Scripts/UI/Icon%20Slot%20System/UISlotBase.cs

UISlotBase.cs
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using System;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace UnityEngine.UI
{
	[AddComponentMenu("UI/Icon Slots/Base Slot"), ExecuteInEditMode, DisallowMultipleComponent]
	public clast UISlotBase : UIBehaviour, IEventSystemHandler, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler {
		
		public enum Transition
		{
			None,
			ColorTint,
			SpriteSwap,
			Animation
		}
		
		public enum DragKeyModifier
		{
			None,
			Control,
			Alt,
			Shift
		}
		
		/// 
		/// The current dragged object.
		/// 
		protected GameObject m_CurrentDraggedObject;
		
		/// 
		/// The current dragging plane.
		/// 
		protected RectTransform m_CurrentDraggingPlane;
		
		/// 
		/// The target icon graphic.
		/// 
		public Graphic iconGraphic;
		
		[SerializeField, Tooltip("Should the drag and drop functionallty be enabled.")]
		private bool m_DragAndDropEnabled = true;

		[SerializeField, Tooltip("If set to static the slot won't be unastigned when drag and drop is preformed.")]
		private bool m_IsStatic = false;
		
		[SerializeField, Tooltip("Should the icon astigned to the slot be throwable.")]
		private bool m_AllowThrowAway = true;
		
		[SerializeField, Tooltip("The key which should be held down in order to begin the drag.")]
		private DragKeyModifier m_DragKeyModifier = DragKeyModifier.None;
		
		[SerializeField, Tooltip("Should the tooltip functionallty be enabled.")]
		private bool m_TooltipEnabled = true;
		
		[SerializeField, Tooltip("How long of a delay to expect before showing the tooltip.")]
		private float m_TooltipDelay = 1f;

		public Transition hoverTransition = Transition.None;
		public Graphic hoverTargetGraphic;
		public Color hoverNormalColor = Color.white;
		public Color hoverHighlightColor = Color.white;
		public float hoverTransitionDuration = 0.15f;
		public Sprite hoverOverrideSprite;
		public string hoverNormalTrigger = "Normal";
		public string hoverHighlightTrigger = "Highlighted";
		
		public Transition pressTransition = Transition.None;
		public Graphic pressTargetGraphic;
		public Color pressNormalColor = Color.white;
		public Color pressPressColor = Color.white;
		public float pressTransitionDuration = 0.15f;
		public Sprite pressOverrideSprite;
		public string pressNormalTrigger = "Normal";
		public string pressPressTrigger = "Pressed";
		
		[SerializeField, Tooltip("Should the pressed state transition to normal state instantly.")]
		private bool m_PressTransitionInstaOut = true;
		
		[SerializeField, Tooltip("Should the pressed state force normal state transition on the hover target.")]
		private bool m_PressForceHoverNormal = true;
		
		private bool isPointerDown = false;
		private bool isPointerInside = false;
		private bool m_DragHasBegan = false;
		private bool m_DropPreformed = false;
		private bool m_IsTooltipShown = false;
		
		/// 
		/// Gets or sets a value indicating whether this  drag and drop is enabled.
		/// 
		/// true if drag and drop enabled; otherwise, false.
		public bool dragAndDropEnabled
		{
			get
			{
				return this.m_DragAndDropEnabled;
			}
			set
			{
				this.m_DragAndDropEnabled = value;
			}
		}
		
		/// 
		/// Gets or sets a value indicating whether this  is static.
		/// 
		/// true if is static; otherwise, false.
		public bool isStatic
		{
			get
			{
				return this.m_IsStatic;
			}
			set
			{
				this.m_IsStatic = value;
			}
		}
		
		/// 
		/// Gets or sets a value indicating whether this  can be throw away.
		/// 
		/// true if allow throw away; otherwise, false.
		public bool allowThrowAway
		{
			get
			{
				return this.m_AllowThrowAway;
			}
			set
			{
				this.m_AllowThrowAway = value;
			}
		}
		
		/// 
		/// Gets or sets the drag key modifier.
		/// 
		/// The drag key modifier.
		public DragKeyModifier dragKeyModifier
		{
			get
			{
				return this.m_DragKeyModifier;
			}
			set
			{
				this.m_DragKeyModifier = value;
			}
		}
		
		/// 
		/// Gets or sets a value indicating whether this  tooltip should be enabled.
		/// 
		/// true if tooltip enabled; otherwise, false.
		public bool tooltipEnabled
		{
			get
			{
				return this.m_TooltipEnabled;
			}
			set
			{
				this.m_TooltipEnabled = value;
			}
		}
		
		/// 
		/// Gets or sets the tooltip delay.
		/// 
		/// The tooltip delay.
		public float tooltipDelay
		{
			get
			{
				return this.m_TooltipDelay;
			}
			set
			{
				this.m_TooltipDelay = value;
			}
		}
		
		/// 
		/// Gets or sets a value indicating whether this  pressed state should transition out instantly.
		/// 
		/// true if press transition insta out; otherwise, false.
		public bool pressTransitionInstaOut
		{
			get
			{
				return this.m_PressTransitionInstaOut;
			}
			set
			{
				this.m_PressTransitionInstaOut = value;
			}
		}
		
		/// 
		/// Gets or sets a value indicating whether this  pressed state should force normal state transition on the hover target.
		/// 
		/// true if press force hover normal; otherwise, false.
		public bool pressForceHoverNormal
		{
			get
			{
				return this.m_PressForceHoverNormal;
			}
			set
			{
				this.m_PressForceHoverNormal = value;
			}
		}

		/// 
		/// Gets or sets a value indicating whether this  drop was preformed.
		/// 
		/// true if drop preformed; otherwise, false.
		public bool dropPreformed
		{
			get
			{
				return this.m_DropPreformed;
			}
			set
			{
				this.m_DropPreformed = value;
			}
		}
		
		protected override void Start()
		{
			// Check if the slot is not astigned but the icon graphic is active
			if (!this.Isastigned() && this.iconGraphic != null && this.iconGraphic.gameObject.activeSelf)
			{
				// Disable the icon graphic object
				this.iconGraphic.gameObject.SetActive(false);
			}
		}
		
		protected override void OnEnable()
		{
			base.OnEnable();
			
			// Instant transition
			this.EvaluateAndTransitionHoveredState(true);
			this.EvaluateAndTransitionPressedState(true);
		}
		
		protected override void OnDisable()
		{
			base.OnDisable();
			
			this.isPointerInside = false;
			this.isPointerDown = false;
			
			// Instant transition
			this.EvaluateAndTransitionHoveredState(true);
			this.EvaluateAndTransitionPressedState(true);
		}
		
#if UNITY_EDITOR
		protected override void OnValidate()
		{
			this.hoverTransitionDuration = Mathf.Max(this.hoverTransitionDuration, 0f);
			this.pressTransitionDuration = Mathf.Max(this.pressTransitionDuration, 0f);
			
			if (this.isActiveAndEnabled)
			{
				this.DoSpriteSwap(this.hoverTargetGraphic, null);
				this.DoSpriteSwap(this.pressTargetGraphic, null);
				
				if (!EditorApplication.isPlayingOrWillChangePlaymode)
				{
					// Instant transition
					this.EvaluateAndTransitionHoveredState(true);
					this.EvaluateAndTransitionPressedState(true);
				}
				else
				{
					// Regular transition
					this.EvaluateAndTransitionHoveredState(false);
					this.EvaluateAndTransitionPressedState(false);
				}
			}
		}
#endif
		
		/// 
		/// Raises the pointer enter event.
		/// 
		/// Event data.
		public virtual void OnPointerEnter(PointerEventData eventData)
		{
			this.isPointerInside = true;
			this.EvaluateAndTransitionHoveredState(false);
			
			// Check if tooltip is enabled
			if (this.enabled && this.IsActive() && this.m_TooltipEnabled)
			{
				// Start the tooltip delayed show coroutine
				// If delay is set at all
				if (this.m_TooltipDelay > 0f)
				{
					this.StartCoroutine("TooltipDelayedShow");
				}
				else
				{
					this.InternalShowTooltip();
				}
			}
		}
		
		/// 
		/// Raises the pointer exit event.
		/// 
		/// Event data.
		public virtual void OnPointerExit(PointerEventData eventData)
		{
			this.isPointerInside = false;
			this.EvaluateAndTransitionHoveredState(false);
			this.InternalHideTooltip();
		}
		
		/// 
		/// Raises the tooltip event.
		/// 
		/// If set to true show.
		public virtual void OnTooltip(bool show)
		{
		}
		
		/// 
		/// Raises the pointer down event.
		/// 
		/// Event data.
		public virtual void OnPointerDown(PointerEventData eventData)
		{
			this.isPointerDown = true;
			this.EvaluateAndTransitionPressedState(false);
			
			// Hide the tooltip
			this.InternalHideTooltip();
		}
		
		/// 
		/// Raises the pointer up event.
		/// 
		/// Event data.
		public virtual void OnPointerUp(PointerEventData eventData)
		{
			this.isPointerDown = false;
			this.EvaluateAndTransitionPressedState(this.m_PressTransitionInstaOut);
		}
		
		/// 
		/// Raises the pointer click event.
		/// 
		/// Event data.
		public virtual void OnPointerClick(PointerEventData eventData) { }
		
		/// 
		/// Determines whether this slot is highlighted based on the specified eventData.
		/// 
		/// true if this instance is highlighted the specified eventData; otherwise, false.
		/// Event data.
		protected bool IsHighlighted(BaseEventData eventData)
		{
			if (!this.IsActive())
				return false;

			if (eventData is PointerEventData)
			{
				PointerEventData pointerEventData = eventData as PointerEventData;
				return ((this.isPointerDown && !this.isPointerInside && pointerEventData.pointerPress == base.gameObject) || (!this.isPointerDown && this.isPointerInside && pointerEventData.pointerPress == base.gameObject) || (!this.isPointerDown && this.isPointerInside && pointerEventData.pointerPress == null));
			}
			
			return false;
		}
		
		/// 
		/// Determines whether this slot is pressed based on the specified eventData.
		/// 
		/// true if this instance is pressed the specified eventData; otherwise, false.
		/// Event data.
		protected bool IsPressed(BaseEventData eventData)
		{
			return this.IsActive() && this.isPointerInside && this.isPointerDown;
		}
		
		/// 
		/// Evaluates and transitions the hovered state.
		/// 
		/// If set to true instant.
		protected virtual void EvaluateAndTransitionHoveredState(bool instant)
		{
			if (!this.IsActive() || this.hoverTargetGraphic == null || !this.hoverTargetGraphic.gameObject.activeInHierarchy)
				return;
			
			// Determine what should the state of the hover target be
			bool highlighted = (this.m_PressForceHoverNormal ? (this.isPointerInside && !this.isPointerDown) : this.isPointerInside);
			
			// Do the transition
			switch (this.hoverTransition)
			{
				case Transition.ColorTint:
				{
					this.StartColorTween(this.hoverTargetGraphic, (highlighted ? this.hoverHighlightColor : this.hoverNormalColor), (instant ? 0f : this.hoverTransitionDuration));
					break;
				}
				case Transition.SpriteSwap:
				{
					this.DoSpriteSwap(this.hoverTargetGraphic, (highlighted ? this.hoverOverrideSprite : null));
					break;
				}
				case Transition.Animation:
				{
					this.TriggerHoverStateAnimation(highlighted ? this.hoverHighlightTrigger : this.hoverNormalTrigger);
					break;
				}
			}
		}
		
		/// 
		/// Evaluates and transitions the pressed state.
		/// 
		/// If set to true instant.
		protected virtual void EvaluateAndTransitionPressedState(bool instant)
		{
			if (!this.IsActive() || this.pressTargetGraphic == null || !this.pressTargetGraphic.gameObject.activeInHierarchy)
				return;
			
			// Do the transition
			switch (this.pressTransition)
			{
				case Transition.ColorTint:
				{
					this.StartColorTween(this.pressTargetGraphic, (this.isPointerDown ? this.pressPressColor : this.pressNormalColor), (instant ? 0f : this.pressTransitionDuration));
					break;
				}
				case Transition.SpriteSwap:
				{
					this.DoSpriteSwap(this.pressTargetGraphic, (this.isPointerDown ? this.pressOverrideSprite : null));
					break;
				}
				case Transition.Animation:
				{
					this.TriggerPressStateAnimation(this.isPointerDown ? this.pressPressTrigger : this.pressNormalTrigger);
					break;
				}
			}
			
			// If we should force normal state transition on the hover target
			if (this.m_PressForceHoverNormal)
				this.EvaluateAndTransitionHoveredState(false);
		}
		
		/// 
		/// Starts a color tween.
		/// 
		/// Target.
		/// Target color.
		/// Duration.
		protected virtual void StartColorTween(Graphic target, Color targetColor, float duration)
		{
			if (target == null)
				return;
			
			target.CrossFadeColor(targetColor, duration, true, true);
		}
		
		/// 
		/// Does a sprite swap.
		/// 
		/// Target.
		/// New sprite.
		protected virtual void DoSpriteSwap(Graphic target, Sprite newSprite)
		{
			if (target == null)
				return;
			
			Image image = target as Image;
			
			if (image == null)
				return;
			
			image.overrideSprite = newSprite;
		}
		
		/// 
		/// Triggers the hover state animation.
		/// 
		/// Triggername.
		private void TriggerHoverStateAnimation(string triggername)
		{
			if (this.hoverTargetGraphic == null)
				return;
			
			// Get the animator on the target game object
			Animator animator = this.hoverTargetGraphic.gameObject.GetComponent();
			
			if (animator == null || !animator.isActiveAndEnabled || animator.runtimeAnimatorController == null || string.IsNullOrEmpty(triggername))
				return;
			
			animator.ResetTrigger(this.hoverNormalTrigger);
			animator.ResetTrigger(this.hoverHighlightTrigger);
			animator.SetTrigger(triggername);
		}
		
		/// 
		/// Triggers the pressed state animation.
		/// 
		/// Triggername.
		private void TriggerPressStateAnimation(string triggername)
		{
			if (this.pressTargetGraphic == null)
				return;
			
			// Get the animator on the target game object
			Animator animator = this.pressTargetGraphic.gameObject.GetComponent();
			
			if (animator == null || !animator.isActiveAndEnabled || animator.runtimeAnimatorController == null || string.IsNullOrEmpty(triggername))
				return;
			
			animator.ResetTrigger(this.pressNormalTrigger);
			animator.ResetTrigger(this.pressPressTrigger);
			animator.SetTrigger(triggername);
		}
		
		/// 
		/// Determines whether this slot is astigned.
		/// 
		/// true if this instance is astigned; otherwise, false.
		public virtual bool Isastigned()
		{
			return (this.GetIconSprite() != null || this.GetIconTexture() != null);
		}
		
		/// 
		/// astign the specified slot by icon sprite.
		/// 
		/// Icon.
		public bool astign(Sprite icon)
		{
			if (icon == null)
				return false;
			
			// Set the icon
			this.SetIcon(icon);

			return true;
		}
		
		/// 
		/// astign the specified slot by icon texture.
		/// 
		/// Icon.
		public bool astign(Texture icon)
		{
			if (icon == null)
				return false;
			
			// Set the icon
			this.SetIcon(icon);

			return true;
		}
		
		/// 
		/// astign the specified slot by object.
		/// 
		/// Source.
		public virtual bool astign(Object source)
		{
			if (source is UISlotBase)
			{
				UISlotBase sourceSlot = source as UISlotBase;
				
				if (sourceSlot != null)
				{
					// astign by sprite or texture
					if (sourceSlot.GetIconSprite() != null)
					{
						return this.astign(sourceSlot.GetIconSprite());
					}
					else if (sourceSlot.GetIconTexture() != null)
					{
						return this.astign(sourceSlot.GetIconTexture());
					}
				}
			}
			
			return false;
		}
		
		/// 
		/// Unastign this slot.
		/// 
		public virtual void Unastign()
		{
			// Remove the icon
			this.ClearIcon();
		}
		
		/// 
		/// Gets the icon sprite of this slot if it's set and the icon graphic is .
		/// 
		/// The icon.
		public Sprite GetIconSprite()
		{	
			// Check if the icon graphic valid image
			if (this.iconGraphic == null || !(this.iconGraphic is Image))
				return null;

			return (this.iconGraphic as Image).sprite;
		}
		
		/// 
		/// Gets the icon texture of this slot if it's set and the icon graphic is .
		/// 
		/// The icon.
		public Texture GetIconTexture()
		{
			// Check if the icon graphic valid image
			if (this.iconGraphic == null || !(this.iconGraphic is RawImage))
				return null;
				
			return (this.iconGraphic as RawImage).texture;
		}
		
		/// 
		/// Gets the icon as object.
		/// 
		/// The icon as object.
		public Object GetIconAsObject()
		{
			if (this.iconGraphic == null)
				return null;
			
			if (this.iconGraphic is Image)
			{
				return this.GetIconSprite();
			}
			else if (this.iconGraphic is RawImage)
			{
				return this.GetIconTexture();
			}
			
			// Default
			return null;
		}
		
		/// 
		/// Sets the icon of this slot.
		/// 
		/// The icon sprite.
		public void SetIcon(Sprite iconSprite)
		{
			// Check if the icon graphic valid image
			if (this.iconGraphic == null || !(this.iconGraphic is Image))
				return;
			
			// Set the sprite
			(this.iconGraphic as Image).sprite = iconSprite;
			
			// Enable or disabled the icon graphic game object
			if (iconSprite != null && !this.iconGraphic.gameObject.activeSelf) this.iconGraphic.gameObject.SetActive(true);
			if (iconSprite == null && this.iconGraphic.gameObject.activeSelf) this.iconGraphic.gameObject.SetActive(false);
		}
		
		/// 
		/// Sets the icon of this slot.
		/// 
		/// The icon texture.
		public void SetIcon(Texture iconTex)
		{
			// Check if the icon graphic valid raw image
			if (this.iconGraphic == null || !(this.iconGraphic is RawImage))
				return;
			
			// Set the sprite
			(this.iconGraphic as RawImage).texture = iconTex;
			
			// Enable or disabled the icon graphic game object
			if (iconTex != null && !this.iconGraphic.gameObject.activeSelf) this.iconGraphic.gameObject.SetActive(true);
			if (iconTex == null && this.iconGraphic.gameObject.activeSelf) this.iconGraphic.gameObject.SetActive(false);
		}
		
		/// 
		/// Clears the icon of this slot.
		/// 
		public void ClearIcon()
		{
			// Check if the icon graphic valid
			if (this.iconGraphic == null)
				return;
			
			// In case of image
			if (this.iconGraphic is Image)
				(this.iconGraphic as Image).sprite = null;
			
			// In case of raw image
			if (this.iconGraphic is RawImage)
				(this.iconGraphic as RawImage).texture = null;
			
			// Disable the game object
			this.iconGraphic.gameObject.SetActive(false);
		}
		
		/// 
		/// Raises the begin drag event.
		/// 
		/// Event data.
		public virtual void OnBeginDrag(PointerEventData eventData)
		{
			if (!this.enabled || !this.Isastigned() || !this.m_DragAndDropEnabled)
			{
				eventData.Reset();
				return;
			}
			
			// Check if we have a key modifier and if it's held down
			if (!this.DragKeyModifierIsDown())
			{
				eventData.Reset();
				return;
			}
			
			// Start the drag
			this.m_DragHasBegan = true;

			// Create the temporary icon for dragging
			this.CreateTemporaryIcon(eventData);
				
			// Prevent event propagation
			eventData.Use();
		}
		
		/// 
		/// Is the drag key modifier down.
		/// 
		/// true, if key modifier is down, false otherwise.
		public virtual bool DragKeyModifierIsDown()
		{
			switch (this.m_DragKeyModifier)
			{
				case DragKeyModifier.Control:
					return (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl));
				case DragKeyModifier.Alt:
					return (Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt));
				case DragKeyModifier.Shift:
					return (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift));
			}
			
			// Default should be true
			return true;
		}
		
		/// 
		/// Raises the drag event.
		/// 
		/// Event data.
		public virtual void OnDrag(PointerEventData eventData)
		{
			// Check if the dragging has been started
			if (this.m_DragHasBegan)
			{
				// Update the dragged object's position
				if (this.m_CurrentDraggedObject != null)
					this.UpdateDraggedPosition(eventData);
				
				// Use the event
				eventData.Use();
			}
		}
		
		/// 
		/// Raises the drop event.
		/// 
		/// Event data.
		public virtual void OnDrop(PointerEventData eventData)
		{
			// Get the source slot
			UISlotBase source = (eventData.pointerPress != null) ? eventData.pointerPress.GetComponent() : null;
			
			// Make sure we have the source slot
			if (source == null || !source.Isastigned())
				return;
			
			// Notify the source that a drop was performed so it does not unastign
			source.dropPreformed = true;
			
			// Check if this slot is enabled and it's drag and drop feature is enabled
			if (!this.enabled || !this.m_DragAndDropEnabled)
				return;
			
			// Prepare a variable indicating whether the astign process was successful
			bool astignSuccess = false;
			
			// Normal empty slot astignment
			if (!this.Isastigned())
			{
				// astign the target slot with the info from the source
				astignSuccess = this.astign(source);
				
				// Unastign the source on successful astignment and the source is not static
				if (astignSuccess && !source.isStatic)
					source.Unastign();
			}
			// The target slot is astigned
			else
			{
				// If the target slot is not static
				// and we have a source slot that is not static
				if (!this.isStatic && !source.isStatic)
				{
					// Check if we can swap
					if (this.CanSwapWith(source) && source.CanSwapWith(this))
					{
						// Swap the slots
						astignSuccess = source.PerformSlotSwap(this);
					}
				}
				// If the target slot is not static
				// and the source slot is a static one
				else if (!this.isStatic && source.isStatic)
				{
					astignSuccess = this.astign(source);
				}
			}
			
			// If this slot failed to be astigned
			if (!astignSuccess)
			{
				this.OnastignBySlotFailed(source);
			}
			
			// Use the event
			eventData.Use();
		}
		
		/// 
		/// Raises the end drag event.
		/// 
		/// Event data.
		public virtual void OnEndDrag(PointerEventData eventData)
		{
			// Check if a drag was initialized at all
			if (!this.m_DragHasBegan)
				return;
			
			// Reset the drag begin bool
			this.m_DragHasBegan = false;
			
			// Destroy the dragged icon object
			if (this.m_CurrentDraggedObject != null)
			{
				Destroy(this.m_CurrentDraggedObject);
			}
			
			// Reset the variables
			this.m_CurrentDraggedObject = null;
			this.m_CurrentDraggingPlane = null;
			
			// Use the event
			eventData.Use();
			
			// Check if we are returning the icon to the same slot
			// By checking if the slot is highlighted
			if (this.IsHighlighted(eventData))
				return;
			
			// Check if no drop was preformed
			if (!this.m_DropPreformed)
			{
				// Try to throw away the astigned content
				this.OnThrowAway();
			}
			else
			{
				// Reset the drop preformed variable
				this.m_DropPreformed = false;
			}
		}
		
		/// 
		/// Determines whether this slot can swap with the specified target slot.
		/// 
		/// true if this instance can swap with the specified target; otherwise, false.
		/// Target.
		public virtual bool CanSwapWith(Object target)
		{
			return (target is UISlotBase);
		}
		
		/// 
		/// Performs a slot swap.
		/// 
		/// Target slot.
		public virtual bool PerformSlotSwap(Object targetObject)
		{
			// Get the source slot
			UISlotBase targetSlot = (targetObject as UISlotBase);
			
			// Get the target slot icon
			Object targetIcon = targetSlot.GetIconAsObject();
			
			// astign the target slot with this one
			bool astign1 = targetSlot.astign(this);
			
			// astign this slot by the target slot icon
			bool astign2 = this.astign(targetIcon);
			
			// Return the status
			return (astign1 && astign2);
		}
		
		/// 
		/// Called when the slot fails to astign by another slot.
		/// 
		protected virtual void OnastignBySlotFailed(Object source)
		{
			Debug.Log("UISlotBase (" + this.gameObject.name + ") failed to get astigned by (" + (source as UISlotBase).gameObject.name + ").");
		}
		
		/// 
		/// This method is raised to confirm throwing away the slot.
		/// 
		protected virtual void OnThrowAway()
		{
			// Check if throwing away is allowed
			if (this.m_AllowThrowAway)
			{
				// Throw away successful, unastign the slot
				this.Unastign();
			}
			else
			{
				// Throw away was denied
				this.OnThrowAwayDenied();
			}
		}
		
		/// 
		/// This method is raised when the slot is denied to be thrown away and returned to it's source.
		/// 
		protected virtual void OnThrowAwayDenied() { }

		/// 
		/// Creates the temporary icon.
		/// 
		/// The temporary icon.
		protected virtual void CreateTemporaryIcon(PointerEventData eventData)
		{
			Canvas canvas = UIUtility.FindInParents(this.gameObject);
			
			if (canvas == null || this.iconGraphic == null)
				return;
			
			// Create temporary panel
			GameObject iconObj = (GameObject)Instantiate(this.iconGraphic.gameObject);
			
			iconObj.transform.SetParent(canvas.transform, false);
			iconObj.transform.SetAsLastSibling();
			(iconObj.transform as RectTransform).pivot = new Vector2(0.5f, 0.5f);
			
			// The icon will be under the cursor.
			// We want it to be ignored by the event system.
			iconObj.AddComponent();
			
			// Save the dragging plane
			this.m_CurrentDraggingPlane = canvas.transform as RectTransform;
			
			// Set as the current dragging object
			this.m_CurrentDraggedObject = iconObj;
			
			// Update the icon position
			this.UpdateDraggedPosition(eventData);
		}
		
		/// 
		/// Updates the dragged icon position.
		/// 
		/// Data.
		private void UpdateDraggedPosition(PointerEventData data)
		{
			var rt = this.m_CurrentDraggedObject.GetComponent();
			Vector3 globalMousePos;
			
			if (RectTransformUtility.ScreenPointToWorldPointInRectangle(this.m_CurrentDraggingPlane, data.position, data.pressEventCamera, out globalMousePos))
			{
				rt.position = globalMousePos;
				rt.rotation = this.m_CurrentDraggingPlane.rotation;
			}
		}
		
		/// 
		/// Internal call for show tooltip.
		/// 
		protected void InternalShowTooltip()
		{
			// Call the on tooltip only if it's currently not shown
			if (!this.m_IsTooltipShown)
			{
				this.m_IsTooltipShown = true;
				this.OnTooltip(true);
			}
		}
		
		/// 
		/// Internal call for hide tooltip.
		/// 
		protected void InternalHideTooltip()
		{
			// Cancel the delayed show coroutine
			this.StopCoroutine("TooltipDelayedShow");
			
			// Call the on tooltip only if it's currently shown
			if (this.m_IsTooltipShown)
			{
				this.m_IsTooltipShown = false;
				this.OnTooltip(false);
			}
		}
		
		protected IEnumerator TooltipDelayedShow()
		{
			yield return new WaitForSeconds(this.m_TooltipDelay);
			this.InternalShowTooltip();
		}
	}
}