From 34333249b20da7ae74f4cd2491e93a331d93266c Mon Sep 17 00:00:00 2001 From: Kadir Date: Sat, 24 Feb 2024 01:34:15 +0300 Subject: [PATCH] TextMeshPro Support & Added SetValueWithoutNotify You can use TextMeshPro instead of legacy text. You can call SetValueWithoutNotify to set the value of Dropdown without invoking callbacks. --- .../UI/Core/DropdownEx/DropdownEx.cs | 124 +++++++++++------- 1 file changed, 73 insertions(+), 51 deletions(-) diff --git a/Assets/Plugins/UnityEngine.UI/UI/Core/DropdownEx/DropdownEx.cs b/Assets/Plugins/UnityEngine.UI/UI/Core/DropdownEx/DropdownEx.cs index f6de4ed..d9a993b 100644 --- a/Assets/Plugins/UnityEngine.UI/UI/Core/DropdownEx/DropdownEx.cs +++ b/Assets/Plugins/UnityEngine.UI/UI/Core/DropdownEx/DropdownEx.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; @@ -27,7 +28,7 @@ public class DropdownEx : Selectable, IPointerClickHandler, ISubmitHandler, ICan protected internal class DropdownItem : MonoBehaviour, IPointerEnterHandler, ICancelHandler { [SerializeField] - private Text m_Text; + private TextMeshProUGUI m_Text; [SerializeField] private Image m_Image; [SerializeField] @@ -35,7 +36,7 @@ protected internal class DropdownItem : MonoBehaviour, IPointerEnterHandler, ICa [SerializeField] private Toggle m_Toggle; - public Text text { get { return m_Text; } set { m_Text = value; } } + public TextMeshProUGUI text { get { return m_Text; } set { m_Text = value; } } public Image image { get { return m_Image; } set { m_Image = value; } } public RectTransform rectTransform { get { return m_RectTransform; } set { m_RectTransform = value; } } public Toggle toggle { get { return m_Toggle; } set { m_Toggle = value; } } @@ -155,12 +156,12 @@ public class DropdownEvent : UnityEvent { } // Text to be used as a caption for the current value. It's not required, but it's kept here for convenience. [SerializeField] - private Text m_CaptionText; + private TextMeshProUGUI m_CaptionText; /// /// The Text component to hold the text of the currently selected option. /// - public Text captionText { get { return m_CaptionText; } set { m_CaptionText = value; RefreshShownValue(); } } + public TextMeshProUGUI captionText { get { return m_CaptionText; } set { m_CaptionText = value; RefreshShownValue(); } } [SerializeField] private Image m_CaptionImage; @@ -173,12 +174,12 @@ public class DropdownEvent : UnityEvent { } [Space] [SerializeField] - private Text m_ItemText; + private TextMeshProUGUI m_ItemText; /// /// The Text component to hold the text of the item. /// - public Text itemText { get { return m_ItemText; } set { m_ItemText = value; RefreshShownValue(); } } + public TextMeshProUGUI itemText { get { return m_ItemText; } set { m_ItemText = value; RefreshShownValue(); } } [SerializeField] private Image m_ItemImage; @@ -437,65 +438,79 @@ public uint value set { - if (Application.isPlaying && (value == m_Value || options.Count == 0)) - return; + Set(value); + } + } - if (AllowMultiSelect) + /// + /// Set the value of Dropdown without invoking callbacks. + /// + /// The new value for the Dropdown. + public void SetValueWithoutNotify(uint input) + { + Set(input, false); + } + + void Set(uint value, bool sendCallback = true) + { + if (Application.isPlaying && (value == m_Value || options.Count == 0)) + return; + if (AllowMultiSelect) + { + // If we invert m_Value and mask it with 'value' + // we will have the bits that have changed + // + // Here's how this works: + // + // so lets say m_Value = 5 00000101 + // and lets say value is 6 00000110 + // so options[1] is added and options[0] is removed + // ~m_Value & value == 11111010 & + // 00000110 + // -------- + // 00000010 <-- index 1 (option #2) + // m_Value & ~value == 00000101 + // 11111001 + // -------- + // 00000001 <-- index 0 (option #1) + uint added_mask = ~m_Value & value; + uint removed_mask = m_Value & ~value; + updateOptionsState(added_mask, removed_mask, sendCallback); + if (m_Dropdown != null) { - // If we invert m_Value and mask it with 'value' - // we will have the bits that have changed + // setting the value will close an open dropdown + // this way when it is opened back up, the toggles + // will reflect the new state. // - // Here's how this works: + // If we set the toggle state here, OnSelected() + // will be called and we will be here all over again. // - // so lets say m_Value = 5 00000101 - // and lets say value is 6 00000110 - // so options[1] is added and options[0] is removed - - // ~m_Value & value == 11111010 & - // 00000110 - // -------- - // 00000010 <-- index 1 (option #2) - - // m_Value & ~value == 00000101 - // 11111001 - // -------- - // 00000001 <-- index 0 (option #1) - - uint added_mask = ~m_Value & value; - uint removed_mask = m_Value & ~value; - updateOptionsState(added_mask, removed_mask); - - if (m_Dropdown != null) - { - // setting the value will close an open dropdown - // this way when it is opened back up, the toggles - // will reflect the new state. - // - // If we set the toggle state here, OnSelected() - // will be called and we will be here all over again. - // - // I guess we could remove the event listener temporarily - // and then set the toggle values to avoid closing an already - // open box but I think this is an edge case. - Hide(); - } + // I guess we could remove the event listener temporarily + // and then set the toggle values to avoid closing an already + // open box but I think this is an edge case. + Hide(); } - else + } + else + { + if (sendCallback) { m_OnItemDeselected.Invoke(m_Value); m_OnItemSelected.Invoke(value); } + } + m_Value = value; + RefreshShownValue(); - m_Value = value; - RefreshShownValue(); - + if (sendCallback) + { // Notify all listeners UISystemProfilerApi.AddMarker("DropdownEx.value", this); m_OnValueChanged.Invoke(m_Value); } } - protected virtual void updateOptionsState(uint added, uint removed) + protected virtual void updateOptionsState(uint added, uint removed, bool sendCallback = true) { uint index = 0; while (added > 0) @@ -503,7 +518,10 @@ protected virtual void updateOptionsState(uint added, uint removed) if ((added & 0x01) == 0x01) { options[(int)index].selected = true; - m_OnItemSelected.Invoke(index); + if (sendCallback) + { + m_OnItemSelected.Invoke(index); + } } index++; @@ -516,7 +534,10 @@ protected virtual void updateOptionsState(uint added, uint removed) if ((removed & 0x01) == 0x01) { options[(int)index].selected = false; - m_OnItemDeselected.Invoke(index); + if (sendCallback) + { + m_OnItemDeselected.Invoke(index); + } } index++; @@ -524,6 +545,7 @@ protected virtual void updateOptionsState(uint added, uint removed) } } + public IEnumerable SelectedOptions { get