< Summary

Class:DCL.ECSComponents.UIDropdown.UIDropdownHandler
Assembly:DCL.ECSComponents.UIDropdown
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ECSComponents/UIDropdown/UIDropdownHandler.cs
Covered lines:32
Uncovered lines:5
Coverable lines:37
Total lines:116
Line coverage:86.4% (32 of 37)
Covered branches:0
Total branches:0
Covered methods:9
Total methods:10
Method coverage:90% (9 of 10)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
UIDropdownHandler(...)0%110100%
OnComponentCreated(...)0%110100%
CreateInputResult(...)0%110100%
OnComponentRemoved(...)0%2100%
OnComponentModelUpdated(...)0%440100%
ApplyTextElementStyle(...)0%110100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ECSComponents/UIDropdown/UIDropdownHandler.cs

#LineLine coverage
 1using DCL.Controllers;
 2using DCL.ECS7.ComponentWrapper;
 3using DCL.ECS7.ComponentWrapper.Generic;
 4using DCL.ECS7.InternalComponents;
 5using DCL.ECSComponents.UIAbstractElements;
 6using DCL.ECSComponents.Utils;
 7using DCL.ECSRuntime;
 8using DCL.Models;
 9using System.Linq;
 10using UnityEngine.UIElements;
 11
 12namespace DCL.ECSComponents.UIDropdown
 13{
 14    public class UIDropdownHandler : UIElementHandlerBase, IECSComponentHandler<PBUiDropdown>
 15    {
 16        // The 'DCL.UIDropdown.uss' stylesheet loaded in DCLDefaultRuntimeTheme scriptable object uses these classes
 17        private const string READONLY_CLASS = "dcl-dropdown-readonly";
 18        private const string CLASS = "dcl-dropdown";
 19        private const string TEXT_ELEMENT_CLASS = "unity-base-popup-field__text";
 20
 21        private UIFontUpdater fontUpdater;
 22        private readonly int resultComponentId;
 23        private readonly IInternalECSComponent<InternalUIInputResults> inputResults;
 24        private readonly AssetPromiseKeeper_Font fontPromiseKeeper;
 25        private readonly WrappedComponentPool<IWrappedComponent<PBUiDropdownResult>> componentPool;
 26
 27        private EventCallback<ChangeEvent<string>> onValueChanged;
 28
 29        // In the future iteration we may want to create our own DropdownField to be able to fully customize
 30        // it according to the user provided styles
 8231        internal DropdownField uiElement { get; private set; }
 32
 1133        internal TextElement textField { get; private set; }
 34
 35        public UIDropdownHandler(IInternalECSComponent<InternalUiContainer> internalUiContainer,
 36            int resultComponentId,
 37            IInternalECSComponent<InternalUIInputResults> inputResults,
 38            AssetPromiseKeeper_Font fontPromiseKeeper,
 39            int componentId,
 40            WrappedComponentPool<IWrappedComponent<PBUiDropdownResult>> componentPool)
 541            : base(internalUiContainer, componentId)
 42        {
 543            this.resultComponentId = resultComponentId;
 544            this.inputResults = inputResults;
 545            this.fontPromiseKeeper = fontPromiseKeeper;
 546            this.componentPool = componentPool;
 547        }
 48
 49        public void OnComponentCreated(IParcelScene scene, IDCLEntity entity)
 50        {
 51            // `DropdownField` contains a label as well but
 52            // passing a null string will actually make it invisible
 553            uiElement = new DropdownField(null);
 554            textField = uiElement.Q<TextElement>(className: TEXT_ELEMENT_CLASS);
 555            uiElement.AddToClassList(CLASS);
 56
 557            AddElementToRoot(scene, entity, uiElement);
 558            fontUpdater = new UIFontUpdater(uiElement, fontPromiseKeeper);
 59
 60            // it seems strange but `DropdownField` notifies with `string`, not `int`
 561            onValueChanged = UIPointerEventsUtils
 62               .RegisterFeedback<ChangeEvent<string>>
 63                (inputResults,
 64                    CreateInputResult,
 65                    scene,
 66                    entity,
 67                    uiElement,
 68                    resultComponentId);
 569        }
 70
 71        private IPooledWrappedComponent CreateInputResult(ChangeEvent<string> onValueChange)
 72        {
 173            var componentPooled = componentPool.Get();
 174            var componentModel = componentPooled.WrappedComponent.Model;
 175            componentModel.Value = uiElement.index;
 176            return componentPooled;
 77        }
 78
 79        public void OnComponentRemoved(IParcelScene scene, IDCLEntity entity)
 80        {
 081            uiElement.UnregisterFeedback(onValueChanged);
 082            RemoveElementFromRoot(scene, entity, uiElement);
 083            uiElement = null;
 084            fontUpdater.Dispose();
 085        }
 86
 87        public void OnComponentModelUpdated(IParcelScene scene, IDCLEntity entity, PBUiDropdown model)
 88        {
 589            fontUpdater.Update(model.GetFont());
 90
 591            uiElement.style.fontSize = model.GetFontSize();
 592            uiElement.style.color = model.GetColor().ToUnityColor();
 93
 594            uiElement.choices.Clear();
 595            uiElement.choices.AddRange(model.Options);
 96
 597            int selectedIndex = model.GetSelectedIndex();
 98
 99            // Don't report the value back to the scene
 100            // there is no `SetIndexWithoutNotify`
 5101            uiElement.SetValueWithoutNotify(uiElement.choices.ElementAtOrDefault(selectedIndex) ?? model.EmptyLabel);
 102
 103            // it is controlled from the style sheet
 5104            uiElement.EnableInClassList(READONLY_CLASS, model.Disabled);
 105            // TODO it's not fully correct
 5106            uiElement.pickingMode = model.Disabled ? PickingMode.Ignore : PickingMode.Position;
 107
 5108            ApplyTextElementStyle(model);
 5109        }
 110
 111        private void ApplyTextElementStyle(PBUiDropdown dropdown)
 112        {
 5113            textField.style.unityTextAlign = dropdown.GetTextAlign().ToUnityTextAlign();
 5114        }
 115    }
 116}