UIGU source code analysis 9: DropDown

Posted by Celadon on Mon, 07 Mar 2022 17:17:51 +0100

Source code 9: DropDown

Dropwon is mainly used to realize the function of drop-down selection

public class Dropdown : Selectable, IPointerClickHandler, ISubmitHandler, ICancelHandler
{

	...
	 protected internal class DropdownItem : MonoBehaviour, IPointerEnterHandler, ICancelHandler
	 {
	 		//Text displayed by Item
     		[SerializeField]
            private Text m_Text;
            //Basemap displayed by Item
            [SerializeField]
            private Image m_Image;
            //rectTransfom of item
            [SerializeField]
            private RectTransform m_RectTransform;
            //Clickable Toggle
            [SerializeField]
            private Toggle m_Toggle;
	 	...
	 }
	...

}

Dropdown inherits from Selectable, and also inherits three interfaces: ipointerclickhandler, isubmithandler and icencelhandler.

The inner board contains a DropdownItem class, which inherits from the two interfaces of monobehavior, ipointenterenterhandler and icencelhandler.

DropdownItem is the drop-down box option that appears when we click

DropdownItem implements ipointenterenterhandler and OnCancel

 public virtual void OnPointerEnter(PointerEventData eventData)
        {
            EventSystem.current.SetSelectedGameObject(gameObject);
        }

        public virtual void OnCancel(BaseEventData eventData)
        {
            Dropdown dropdown = GetComponentInParent<Dropdown>();
            if (dropdown)
                dropdown.Hide();
        }

When the mouse is drawn in, call SetSelectedGameObject of EventSystem to set this object as the selected object, which shows that the background color of the Item object has changed.

When you press the key to cancel, the Hide drop-down list of dropdown will be called

[SerializeField]
private int m_Value;
        
[SerializeField]
 private OptionDataList m_Options = new OptionDataList();

M in DropDwon_ Value is the m value selected by the record_ Index corresponding to the value in options

m_Value is a property. Set method will be called when setting value

    void Set(int value, bool sendCallback = true)
    {
        if (Application.isPlaying && (value == m_Value || options.Count == 0))
            return;

        m_Value = Mathf.Clamp(value, 0, options.Count - 1);
        RefreshShownValue();

        if (sendCallback)
        {
            // Notify all listeners
            UISystemProfilerApi.AddMarker("Dropdown.value", this);
            m_OnValueChanged.Invoke(m_Value);
        }
    }

    public void RefreshShownValue()
    {
        OptionData data = s_NoOptionData;

        if (options.Count > 0)
            data = options[Mathf.Clamp(m_Value, 0, options.Count - 1)];

        if (m_CaptionText)
        {
            if (data != null && data.text != null)
                m_CaptionText.text = data.text;
            else
                m_CaptionText.text = "";
        }

        if (m_CaptionImage)
        {
            if (data != null)
                m_CaptionImage.sprite = data.image;
            else
                m_CaptionImage.sprite = null;
            m_CaptionImage.enabled = (m_CaptionImage.sprite != null);
        }

When setting m_value will call the RefreshShownValue method and send m_OnValueChanged event

RefreshShownValue is mainly used to refresh the display of DropDown and fetch the current M_ The value (picture and Text) corresponding to value is set in DropDown

When clicking, OnPointerClick will be called to Show the list (the same is true for OnSubmit)

 public virtual void OnPointerClick(PointerEventData eventData)
        {
            Show();
        }

The code of Show is relatively long and will not be posted. The main operations are as follows

  1. Call the SetupTemplate method to set the template. Add DropdownItem for Item, M_ Add Canvas to the template, set overrideSorting to true, sortingOrder to 30000, and display the option table in the front as much as possible. Then add GraphicRaycaster and Canvas group components to accept mouse events.
  2. CreateDropdownList, instantiate the DropDown instance, and SetParent set the parent node
  3. Get the DropdownItem, create the Item with the DropdownItem as the template, and fill in the data. Set the toggle status and add the onValueChanged event of toggle.
  4. Set the size of content according to the number of items. Content is the content object in ScrollRect. And if the height of the DropDownList is greater than the height of the content, its height will be corrected to be the same as the content.
  5. Then judge whether the four corners of the DropDownList exceed the boundary of the rootCanvas (the highest Canvas of the Dropdown), flip the DropDownList (if the four corners of the DropDownList exceed the minimum value of the rootCanvas, pop it up, otherwise pop it down), and then set the position and size of the Item.
  6. By adjusting the alpha value of CanvasGroup, the drop down list is displayed in a gradient, and m_Template and itemTemplate are set to invalid.
  7. Call CreateBlocker to create blocker. Blocker is at the next level of rootCanvas, and its size is the same as that of rootCanvas. sortingOrder is 1 (29999) smaller than that of Dropdown List. The Image component is added, the color is fully transparent, the Button component is added, the listening of onClick is added, and the Hide method is called back. From this, we can know that blocker is used to block mouse events, that is, when the Dropdown List is displayed, clicking on the area outside the option table only hides the option table and will not trigger other components.
  8. Hide method, the Alpha gradient hides the Dropdown List, and destroys all items and dropdown lists after the gradient ends. Then Destroy blocker. Finally, set the object to Select.

Dropdown overrides the Start method and creates a new tweetrunner variable m of FloatTween type_ Alphatweenrunner is initialized. This variable performs the transparency gradient effect when displaying / hiding the drop down list.

    protected override void Start()
    {
        m_AlphaTweenRunner = new TweenRunner<FloatTween>();
        m_AlphaTweenRunner.Init(this);
        base.Start();

        RefreshShownValue();
    }

   private void AlphaFadeList(float duration, float start, float end)
    {
        if (end.Equals(start))
            return;

        FloatTween tween = new FloatTween {duration = duration, startValue = start, targetValue = end};
        tween.AddOnChangedCallback(SetAlpha);
        tween.ignoreTimeScale = true;
        m_AlphaTweenRunner.StartTween(tween);
    }

Topics: Unity Unity3d