Author Topic: UIDragDropItem - Press-And-Hold bug  (Read 3666 times)

cr4y

  • Newbie
  • *
  • Thank You
  • -Given: 4
  • -Receive: 0
  • Posts: 5
    • View Profile
UIDragDropItem - Press-And-Hold bug
« on: January 20, 2015, 07:17:57 AM »
Hi,

I'd like to show something that was working correctly in 3.6.4b (and maybe 2-3 versions after that) and is buggy since then.

Example made in NGUI 3.7.9:
https://www.youtube.com/watch?v=dH_6Kl8V35M

As you can clearly see, Press and hold restriction in UIDragDropItem is not working anymore.
We spent few hours on trying to fix it, but failed. Could you make it work again?

Thanks in advance,
Kris

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIDragDropItem - Press-And-Hold bug
« Reply #1 on: January 20, 2015, 10:23:51 PM »
Thanks, here's the fixed version:
  1. //----------------------------------------------
  2. //            NGUI: Next-Gen UI kit
  3. // Copyright © 2011-2015 Tasharen Entertainment
  4. //----------------------------------------------
  5.  
  6. using UnityEngine;
  7. using System.Collections;
  8.  
  9. /// <summary>
  10. /// UIDragDropItem is a base script for your own Drag & Drop operations.
  11. /// </summary>
  12.  
  13. [AddComponentMenu("NGUI/Interaction/Drag and Drop Item")]
  14. public class UIDragDropItem : MonoBehaviour
  15. {
  16.         public enum Restriction
  17.         {
  18.                 None,
  19.                 Horizontal,
  20.                 Vertical,
  21.                 PressAndHold,
  22.         }
  23.  
  24.         /// <summary>
  25.         /// What kind of restriction is applied to the drag & drop logic before dragging is made possible.
  26.         /// </summary>
  27.  
  28.         public Restriction restriction = Restriction.None;
  29.  
  30.         /// <summary>
  31.         /// Whether a copy of the item will be dragged instead of the item itself.
  32.         /// </summary>
  33.  
  34.         public bool cloneOnDrag = false;
  35.  
  36.         /// <summary>
  37.         /// How long the user has to press on an item before the drag action activates.
  38.         /// </summary>
  39.  
  40.         [HideInInspector]
  41.         public float pressAndHoldDelay = 1f;
  42.  
  43. #region Common functionality
  44.  
  45.         [System.NonSerialized] protected Transform mTrans;
  46.         [System.NonSerialized] protected Transform mParent;
  47.         [System.NonSerialized] protected Collider mCollider;
  48.         [System.NonSerialized] protected Collider2D mCollider2D;
  49.         [System.NonSerialized] protected UIButton mButton;
  50.         [System.NonSerialized] protected UIRoot mRoot;
  51.         [System.NonSerialized] protected UIGrid mGrid;
  52.         [System.NonSerialized] protected UITable mTable;
  53.         [System.NonSerialized] protected float mDragStartTime = 0f;
  54.         [System.NonSerialized] protected UIDragScrollView mDragScrollView = null;
  55.         [System.NonSerialized] protected bool mPressed = false;
  56.         [System.NonSerialized] protected bool mDragging = false;
  57.         [System.NonSerialized] protected UICamera.MouseOrTouch mTouch;
  58.  
  59.         /// <summary>
  60.         /// Cache the transform.
  61.         /// </summary>
  62.  
  63.         protected virtual void Start ()
  64.         {
  65.                 mTrans = transform;
  66. #if UNITY_4_3 || UNITY_4_5 || UNITY_4_6
  67.                 mCollider = collider;
  68.                 mCollider2D = collider2D;
  69. #else
  70.                 mCollider = gameObject.GetComponent<Collider>();
  71.                 mCollider2D = gameObject.GetComponent<Collider2D>();
  72. #endif
  73.                 mButton = GetComponent<UIButton>();
  74.                 mDragScrollView = GetComponent<UIDragScrollView>();
  75.         }
  76.  
  77.         /// <summary>
  78.         /// Record the time the item was pressed on.
  79.         /// </summary>
  80.  
  81.         protected void OnPress (bool isPressed)
  82.         {
  83.                 if (isPressed)
  84.                 {
  85.                         mTouch = UICamera.currentTouch;
  86.                         mDragStartTime = RealTime.time + pressAndHoldDelay;
  87.                         mPressed = true;
  88.                 }
  89.                 else
  90.                 {
  91.                         mPressed = false;
  92.                         mTouch = null;
  93.                 }
  94.         }
  95.  
  96.         /// <summary>
  97.         /// Start the dragging operation after the item was held for a while.
  98.         /// </summary>
  99.  
  100.         protected virtual void Update ()
  101.         {
  102.                 if (restriction == Restriction.PressAndHold)
  103.                 {
  104.                         if (mPressed && !mDragging && mDragStartTime < RealTime.time)
  105.                                 StartDragging();
  106.                 }
  107.         }
  108.  
  109.         /// <summary>
  110.         /// Start the dragging operation.
  111.         /// </summary>
  112.  
  113.         protected void OnDragStart ()
  114.         {
  115.                 if (!enabled || mTouch != UICamera.currentTouch) return;
  116.  
  117.                 // If we have a restriction, check to see if its condition has been met first
  118.                 if (restriction != Restriction.None)
  119.                 {
  120.                         if (restriction == Restriction.Horizontal)
  121.                         {
  122.                                 Vector2 delta = mTouch.totalDelta;
  123.                                 if (Mathf.Abs(delta.x) < Mathf.Abs(delta.y)) return;
  124.                         }
  125.                         else if (restriction == Restriction.Vertical)
  126.                         {
  127.                                 Vector2 delta = mTouch.totalDelta;
  128.                                 if (Mathf.Abs(delta.x) > Mathf.Abs(delta.y)) return;
  129.                         }
  130.                         else if (restriction == Restriction.PressAndHold)
  131.                         {
  132.                                 // Checked in Update instead
  133.                                 return;
  134.                         }
  135.                 }
  136.                 StartDragging();
  137.         }
  138.  
  139.         /// <summary>
  140.         /// Start the dragging operation.
  141.         /// </summary>
  142.  
  143.         protected virtual void StartDragging ()
  144.         {
  145.                 if (!mDragging)
  146.                 {
  147.                         if (cloneOnDrag)
  148.                         {
  149.                                 mPressed = false;
  150.                                 GameObject clone = NGUITools.AddChild(transform.parent.gameObject, gameObject);
  151.                                 clone.transform.localPosition = transform.localPosition;
  152.                                 clone.transform.localRotation = transform.localRotation;
  153.                                 clone.transform.localScale = transform.localScale;
  154.  
  155.                                 UIButtonColor bc = clone.GetComponent<UIButtonColor>();
  156.                                 if (bc != null) bc.defaultColor = GetComponent<UIButtonColor>().defaultColor;
  157.  
  158.                                 if (mTouch != null && mTouch.pressed == gameObject)
  159.                                 {
  160.                                         mTouch.current = clone;
  161.                                         mTouch.pressed = clone;
  162.                                         mTouch.dragged = clone;
  163.                                         mTouch.last = clone;
  164.                                 }
  165.  
  166.                                 UIDragDropItem item = clone.GetComponent<UIDragDropItem>();
  167.                                 item.mTouch = mTouch;
  168.                                 item.mPressed = true;
  169.                                 item.mDragging = true;
  170.                                 item.Start();
  171.                                 item.OnDragDropStart();
  172.  
  173.                                 if (UICamera.currentTouch == null)
  174.                                         UICamera.currentTouch = mTouch;
  175.  
  176.                                 mTouch = null;
  177.  
  178.                                 UICamera.Notify(gameObject, "OnPress", false);
  179.                                 UICamera.Notify(gameObject, "OnHover", false);
  180.                         }
  181.                         else
  182.                         {
  183.                                 mDragging = true;
  184.                                 OnDragDropStart();
  185.                         }
  186.                 }
  187.         }
  188.  
  189.         /// <summary>
  190.         /// Perform the dragging.
  191.         /// </summary>
  192.  
  193.         protected void OnDrag (Vector2 delta)
  194.         {
  195.                 if (!mDragging || !enabled || mTouch != UICamera.currentTouch) return;
  196.                 OnDragDropMove(delta * mRoot.pixelSizeAdjustment);
  197.         }
  198.  
  199.         /// <summary>
  200.         /// Notification sent when the drag event has ended.
  201.         /// </summary>
  202.  
  203.         protected void OnDragEnd ()
  204.         {
  205.                 if (!enabled || mTouch != UICamera.currentTouch) return;
  206.                 StopDragging(UICamera.hoveredObject);
  207.         }
  208.  
  209.         /// <summary>
  210.         /// Drop the dragged item.
  211.         /// </summary>
  212.  
  213.         public void StopDragging (GameObject go)
  214.         {
  215.                 if (mDragging)
  216.                 {
  217.                         mDragging = false;
  218.                         OnDragDropRelease(go);
  219.                 }
  220.         }
  221.  
  222. #endregion
  223.  
  224.         /// <summary>
  225.         /// Perform any logic related to starting the drag & drop operation.
  226.         /// </summary>
  227.  
  228.         protected virtual void OnDragDropStart ()
  229.         {
  230.                 // Automatically disable the scroll view
  231.                 if (mDragScrollView != null) mDragScrollView.enabled = false;
  232.  
  233.                 // Disable the collider so that it doesn't intercept events
  234.                 if (mButton != null) mButton.isEnabled = false;
  235.                 else if (mCollider != null) mCollider.enabled = false;
  236.                 else if (mCollider2D != null) mCollider2D.enabled = false;
  237.  
  238.                 mParent = mTrans.parent;
  239.                 mRoot = NGUITools.FindInParents<UIRoot>(mParent);
  240.                 mGrid = NGUITools.FindInParents<UIGrid>(mParent);
  241.                 mTable = NGUITools.FindInParents<UITable>(mParent);
  242.  
  243.                 // Re-parent the item
  244.                 if (UIDragDropRoot.root != null)
  245.                         mTrans.parent = UIDragDropRoot.root;
  246.  
  247.                 Vector3 pos = mTrans.localPosition;
  248.                 pos.z = 0f;
  249.                 mTrans.localPosition = pos;
  250.  
  251.                 TweenPosition tp = GetComponent<TweenPosition>();
  252.                 if (tp != null) tp.enabled = false;
  253.  
  254.                 SpringPosition sp = GetComponent<SpringPosition>();
  255.                 if (sp != null) sp.enabled = false;
  256.  
  257.                 // Notify the widgets that the parent has changed
  258.                 NGUITools.MarkParentAsChanged(gameObject);
  259.  
  260.                 if (mTable != null) mTable.repositionNow = true;
  261.                 if (mGrid != null) mGrid.repositionNow = true;
  262.         }
  263.  
  264.         /// <summary>
  265.         /// Adjust the dragged object's position.
  266.         /// </summary>
  267.  
  268.         protected virtual void OnDragDropMove (Vector2 delta)
  269.         {
  270.                 mTrans.localPosition += (Vector3)delta;
  271.         }
  272.  
  273.         /// <summary>
  274.         /// Drop the item onto the specified object.
  275.         /// </summary>
  276.  
  277.         protected virtual void OnDragDropRelease (GameObject surface)
  278.         {
  279.                 if (!cloneOnDrag)
  280.                 {
  281.                         // Re-enable the collider
  282.                         if (mButton != null) mButton.isEnabled = true;
  283.                         else if (mCollider != null) mCollider.enabled = true;
  284.                         else if (mCollider2D != null) mCollider2D.enabled = true;
  285.  
  286.                         // Is there a droppable container?
  287.                         UIDragDropContainer container = surface ? NGUITools.FindInParents<UIDragDropContainer>(surface) : null;
  288.  
  289.                         if (container != null)
  290.                         {
  291.                                 // Container found -- parent this object to the container
  292.                                 mTrans.parent = (container.reparentTarget != null) ? container.reparentTarget : container.transform;
  293.  
  294.                                 Vector3 pos = mTrans.localPosition;
  295.                                 pos.z = 0f;
  296.                                 mTrans.localPosition = pos;
  297.                         }
  298.                         else
  299.                         {
  300.                                 // No valid container under the mouse -- revert the item's parent
  301.                                 mTrans.parent = mParent;
  302.                         }
  303.  
  304.                         // Update the grid and table references
  305.                         mParent = mTrans.parent;
  306.                         mGrid = NGUITools.FindInParents<UIGrid>(mParent);
  307.                         mTable = NGUITools.FindInParents<UITable>(mParent);
  308.  
  309.                         // Re-enable the drag scroll view script
  310.                         if (mDragScrollView != null)
  311.                                 StartCoroutine(EnableDragScrollView());
  312.  
  313.                         // Notify the widgets that the parent has changed
  314.                         NGUITools.MarkParentAsChanged(gameObject);
  315.  
  316.                         if (mTable != null) mTable.repositionNow = true;
  317.                         if (mGrid != null) mGrid.repositionNow = true;
  318.  
  319.                         // We're now done
  320.                         OnDragDropEnd();
  321.                 }
  322.                 else NGUITools.Destroy(gameObject);
  323.         }
  324.  
  325.         /// <summary>
  326.         /// Function called when the object gets reparented after the drop operation finishes.
  327.         /// </summary>
  328.  
  329.         protected virtual void OnDragDropEnd () { }
  330.  
  331.         /// <summary>
  332.         /// Re-enable the drag scroll view script at the end of the frame.
  333.         /// Reason: http://www.tasharen.com/forum/index.php?topic=10203.0
  334.         /// </summary>
  335.  
  336.         protected IEnumerator EnableDragScrollView ()
  337.         {
  338.                 yield return new WaitForEndOfFrame();
  339.                 if (mDragScrollView != null) mDragScrollView.enabled = true;
  340.         }
  341. }
  342.