Unity-UI-Extensions/com.unity.uiextensions

Items container position is off when the text is empty, DisplayAbove is true, and (ItemsToDisplay < _panelItems.Count)

Closed this issue · 4 comments

Issue created by Nebojsa Brindic as Bitbucket Issue #​393 on 2021.12.30 08:36.
It appears you are calculating the position of the dropdown items container in regards to all items, not displayed items. I had to change RedrawPanel()method, so it looks like this:

private void RedrawPanel()
        {
            float scrollbarWidth = _panelItems.Count > ItemsToDisplay ? _scrollBarWidth : 0f;//hide the scrollbar if there's not enough items
            _scrollBarRT.gameObject.SetActive(_panelItems.Count > ItemsToDisplay);
            if (!_hasDrawnOnce || _rectTransform.sizeDelta != _inputRT.sizeDelta)
            {
                _hasDrawnOnce = true;
                _inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x);
                _inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _rectTransform.sizeDelta.y);

                // CHANGE BEGIN - NEXT 3 LINES ADDED
                var itemsRemaining = _panelItems.Count - ItemsToDisplay;
                if (itemsRemaining < 0)
                    itemsRemaining = 0;
                // CHANGE END

                _scrollPanelRT.SetParent(transform, true);//break the scroll panel from the overlay
                _scrollPanelRT.anchoredPosition = _displayPanelAbove ?
                    // CHANGE BEGIN - THE NEXT LINE IS CHANGED
                    new Vector2(0, DropdownOffset + _rectTransform.sizeDelta.y * (_panelItems.Count - itemsRemaining) - 1) :
                    // CHANGE END
                    new Vector2(0, -_rectTransform.sizeDelta.y);

                //make the overlay fill the screen
                _overlayRT.SetParent(_canvas.transform, false); //attach it to top level object
                _overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _canvasRT.sizeDelta.x);
                _overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _canvasRT.sizeDelta.y);

                _overlayRT.SetParent(transform, true);//reattach to this object
                _scrollPanelRT.SetParent(_overlayRT, true); //reattach the scrollpanel to the overlay
            }

            if (_panelItems.Count < 1) return;

            float dropdownHeight = _rectTransform.sizeDelta.y * Mathf.Min(_itemsToDisplay, _panelItems.Count) + DropdownOffset;

            _scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
            _scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x);

            _itemsPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _scrollPanelRT.sizeDelta.x - scrollbarWidth - 5);
            _itemsPanelRT.anchoredPosition = new Vector2(5, 0);

            _scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
            _scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
            if (scrollbarWidth == 0) _scrollHandleRT.gameObject.SetActive(false); else _scrollHandleRT.gameObject.SetActive(true);

            _slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 0);
            _slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight - _scrollBarRT.sizeDelta.x);
        }

Furthermore, when you are adding the items dynamically through the code, by using any of the methods SetAvailableOptions(...), you need to call RedrawPanel() at the end of these methods in order to make whole panel displayed correctly when the toggle arrow button is clicked. I realized this when I tried to open the dropdown without typing any text in it, but it appeared without scrollbar. Anyway, my methods for setting the items are looking like this:

        public void SetAvailableOptions(List<string> newOptions)
        {
            var uniqueOptions = newOptions.Distinct().ToArray();
            SetAvailableOptions(uniqueOptions);
        }

        public void SetAvailableOptions(string[] newOptions)
        {
            var uniqueOptions = newOptions.Distinct().ToList();
            if (newOptions.Length != uniqueOptions.Count)
                Debug.LogWarning($"{nameof(AutoCompleteComboBox)}.{nameof(SetAvailableOptions)}: items may only exists once. {newOptions.Length - uniqueOptions.Count} duplicates.");

            this.AvailableOptions.Clear();
            for (int i = 0; i < newOptions.Length; i++)
                this.AvailableOptions.Add(newOptions[i]);

            this.RebuildPanel();
            this.RedrawPanel();
        }

On 2021.12.30 08:54 Nebojsa Brindic modified issue:
attachment changed /UnityUIExtensions/unity-ui-extensions/issues/attachments/393/UnityUIExtensions/unity-ui-extensions/1640854489.23/393/autocomplete-err-1.jpgautocomplete-err-1.jpg

On 2021.12.30 08:54, Nebojsa Brindic commented:



On 2021.12.30 08:54 Nebojsa Brindic modified issue:
attachment changed /UnityUIExtensions/unity-ui-extensions/issues/attachments/393/UnityUIExtensions/unity-ui-extensions/1640854489.56/393/autocomplete-err-2.jpgautocomplete-err-2.jpg

On 2022.01.17 11:55, @SimonDarksideJ commented:
Thanks for the tip, will get this incorporated asap