< Summary

Class:AvatarEditorHUDView
Assembly:AvatarEditorHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/AvatarEditorHUD/Scripts/AvatarEditorHUDView.cs
Covered lines:154
Uncovered lines:44
Coverable lines:198
Total lines:452
Line coverage:77.7% (154 of 198)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
AvatarEditorHUDView()0%110100%
Initialize()0%110100%
AvatarEditorHUDView()0%110100%
Awake()0%220100%
OnDestroy()0%110100%
CloseAction_OnTriggered(...)0%6200%
Initialize(...)0%110100%
SetIsWeb3(...)0%110100%
InitializeNavigationEvents()0%220100%
InitializeNavigationInfo(...)0%110100%
InitializeWearableChangeEvents()0%220100%
Create(...)0%110100%
UpdateSelectedBody(...)0%330100%
EquipWearable(...)0%110100%
UnequipWearable(...)0%110100%
SetWearableLoadingSpinner(...)0%220100%
ClearWearablesLoadingSpinner()0%220100%
SelectHairColor(...)0%110100%
SelectSkinColor(...)0%110100%
SelectEyeColor(...)0%110100%
SetColors(...)0%110100%
UnselectAllWearables()0%330100%
UpdateAvatarPreview(...)0%4.074083.33%
AddWearable(...)0%4.594066.67%
RemoveWearable(...)0%20400%
RemoveAllWearables()0%220100%
OnRandomizeButton()0%12300%
OnDoneButton()0%2100%
OnExitButton()0%6200%
OnSnapshotsReady(...)0%2100%
OnSnapshotsFailed()0%2100%
SetVisibility(...)0%770100%
CleanUp()0%10100100%
ShowCollectiblesLoadingSpinner(...)0%110100%
ShowCollectiblesLoadingRetry(...)0%110100%
SetExitButtonActive(...)0%2100%
SetAsFullScreenMenuMode(...)0%4.422015.38%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/AvatarEditorHUD/Scripts/AvatarEditorHUDView.cs

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Runtime.CompilerServices;
 3using UnityEngine;
 4using UnityEngine.UI;
 5
 6[assembly: InternalsVisibleTo("AvatarEditorHUDTests")]
 7
 8public class AvatarEditorHUDView : MonoBehaviour
 9{
 110    private static readonly int RANDOMIZE_ANIMATOR_LOADING_BOOL = Animator.StringToHash("Loading");
 11    private const string VIEW_PATH = "AvatarEditorHUD";
 12    private const string VIEW_OBJECT_NAME = "_AvatarEditorHUD";
 13
 014    public bool isOpen { get; private set; }
 15
 16    [System.Serializable]
 17    public class AvatarEditorNavigationInfo
 18    {
 19        public Toggle toggle;
 20        public Canvas canvas;
 21        public bool enabledByDefault;
 22        public CharacterPreviewController.CameraFocus focus = CharacterPreviewController.CameraFocus.DefaultEditing;
 23
 24        //To remove when we refactor this to avoid ToggleGroup issues when quitting application
 174825        public void Initialize() { Application.quitting += () => toggle.onValueChanged.RemoveAllListeners(); }
 26    }
 27
 28    [System.Serializable]
 29    public class AvatarEditorWearableFilter
 30    {
 31        public string categoryFilter;
 32        public ItemSelector selector;
 33    }
 34
 35    [SerializeField]
 36    internal InputAction_Trigger closeAction;
 37
 38    [SerializeField]
 39    internal Canvas avatarEditorCanvas;
 40
 41    [SerializeField]
 42    internal CanvasGroup avatarEditorCanvasGroup;
 43
 44    [SerializeField]
 45    internal AvatarEditorNavigationInfo[] navigationInfos;
 46
 47    [SerializeField]
 48    internal AvatarEditorWearableFilter[] wearableGridPairs;
 49
 50    [SerializeField]
 51    internal AvatarEditorNavigationInfo collectiblesNavigationInfo;
 52
 53    [SerializeField]
 54    internal ItemSelector collectiblesItemSelector;
 55
 56    [SerializeField]
 57    internal ColorSelector skinColorSelector;
 58
 59    [SerializeField]
 60    internal ColorSelector eyeColorSelector;
 61
 62    [SerializeField]
 63    internal ColorSelector hairColorSelector;
 64
 65    [SerializeField]
 66    internal GameObject characterPreviewPrefab;
 67
 68    [SerializeField]
 69    internal PreviewCameraRotation characterPreviewRotation;
 70
 71    [SerializeField]
 72    internal Button randomizeButton;
 73
 74    [SerializeField]
 75    internal Animator randomizeAnimator;
 76
 77    [SerializeField]
 78    internal Button doneButton;
 79
 80    [SerializeField]
 81    internal Button exitButton;
 82
 83    [SerializeField] internal GameObject loadingSpinnerGameObject;
 84
 85    [Header("Collectibles")]
 86    [SerializeField]
 87    internal GameObject web3Container;
 88
 89    [SerializeField]
 90    internal Button web3GoToMarketplaceButton;
 91
 92    [SerializeField]
 93    internal GameObject noWeb3Container;
 94
 95    [SerializeField]
 96    internal Button noWeb3GoToMarketplaceButton;
 97
 98    internal static CharacterPreviewController characterPreviewController;
 99    private AvatarEditorHUDController controller;
 48100    internal readonly Dictionary<string, ItemSelector> selectorsByCategory = new Dictionary<string, ItemSelector>();
 48101    private readonly HashSet<WearableItem> wearablesWithLoadingSpinner = new HashSet<WearableItem>();
 102
 103    public event System.Action<AvatarModel> OnAvatarAppear;
 104    public event System.Action<bool> OnSetVisibility;
 105    public event System.Action OnRandomize;
 106    public event System.Action OnCloseActionTriggered;
 107
 108    private void Awake()
 109    {
 46110        closeAction.OnTriggered += CloseAction_OnTriggered;
 46111        loadingSpinnerGameObject.SetActive(false);
 46112        doneButton.interactable = false; //the default state of the button should be disable until a profile has been lo
 46113        if (characterPreviewController == null)
 114        {
 46115            characterPreviewController = GameObject.Instantiate(characterPreviewPrefab).GetComponent<CharacterPreviewCon
 46116            characterPreviewController.name = "_CharacterPreviewController";
 117        }
 118
 46119        isOpen = false;
 46120    }
 121
 92122    private void OnDestroy() { closeAction.OnTriggered -= CloseAction_OnTriggered; }
 123
 0124    private void CloseAction_OnTriggered(DCLAction_Trigger action) { OnCloseActionTriggered?.Invoke(); }
 125
 126    private void Initialize(AvatarEditorHUDController controller)
 127    {
 46128        ItemToggle.getEquippedWearablesReplacedByFunc = controller.GetWearablesReplacedBy;
 46129        this.controller = controller;
 46130        gameObject.name = VIEW_OBJECT_NAME;
 131
 46132        randomizeButton.onClick.AddListener(OnRandomizeButton);
 46133        doneButton.onClick.AddListener(OnDoneButton);
 46134        exitButton.onClick.AddListener(OnExitButton);
 46135        InitializeNavigationEvents();
 46136        InitializeWearableChangeEvents();
 137
 46138        web3GoToMarketplaceButton.onClick.RemoveAllListeners();
 46139        noWeb3GoToMarketplaceButton.onClick.RemoveAllListeners();
 46140        web3GoToMarketplaceButton.onClick.AddListener(controller.GoToMarketplace);
 46141        noWeb3GoToMarketplaceButton.onClick.AddListener(controller.GoToMarketplace);
 142
 46143        characterPreviewController.camera.enabled = false;
 46144    }
 145
 146    public void SetIsWeb3(bool isWeb3User)
 147    {
 99148        web3Container.SetActive(isWeb3User);
 99149        noWeb3Container.SetActive(!isWeb3User);
 99150    }
 151
 152    private void InitializeNavigationEvents()
 153    {
 1748154        for (int i = 0; i < navigationInfos.Length; i++)
 155        {
 828156            InitializeNavigationInfo(navigationInfos[i]);
 157        }
 158
 46159        InitializeNavigationInfo(collectiblesNavigationInfo);
 160
 46161        characterPreviewRotation.OnHorizontalRotation += characterPreviewController.Rotate;
 46162    }
 163
 164    private void InitializeNavigationInfo(AvatarEditorNavigationInfo current)
 165    {
 874166        current.Initialize();
 167
 874168        current.toggle.isOn = current.enabledByDefault;
 169
 874170        current.canvas.gameObject.SetActive(current.enabledByDefault);
 874171        current.toggle.onValueChanged.AddListener((on) =>
 172        {
 0173            current.canvas.gameObject.SetActive(@on);
 0174            characterPreviewController.SetFocus(current.focus);
 0175        });
 874176    }
 177
 178    private void InitializeWearableChangeEvents()
 179    {
 46180        int nPairs = wearableGridPairs.Length;
 1564181        for (int i = 0; i < nPairs; i++)
 182        {
 736183            wearableGridPairs[i].selector.OnItemClicked += controller.WearableClicked;
 736184            wearableGridPairs[i].selector.OnSellClicked += controller.SellCollectible;
 736185            selectorsByCategory.Add(wearableGridPairs[i].categoryFilter, wearableGridPairs[i].selector);
 186        }
 187
 46188        collectiblesItemSelector.OnItemClicked += controller.WearableClicked;
 46189        collectiblesItemSelector.OnSellClicked += controller.SellCollectible;
 46190        collectiblesItemSelector.OnRetryClicked += controller.RetryLoadOwnedWearables;
 191
 46192        skinColorSelector.OnColorChanged += controller.SkinColorClicked;
 46193        eyeColorSelector.OnColorChanged += controller.EyesColorClicked;
 46194        hairColorSelector.OnColorChanged += controller.HairColorClicked;
 46195    }
 196
 197    internal static AvatarEditorHUDView Create(AvatarEditorHUDController controller)
 198    {
 46199        var view = Instantiate(Resources.Load<GameObject>(VIEW_PATH)).GetComponent<AvatarEditorHUDView>();
 46200        view.Initialize(controller);
 46201        return view;
 202    }
 203
 204    public void UpdateSelectedBody(WearableItem bodyShape)
 205    {
 1700206        for (int i = 0; i < wearableGridPairs.Length; i++)
 207        {
 800208            if (wearableGridPairs[i].categoryFilter == WearableLiterals.Categories.BODY_SHAPE)
 209            {
 50210                wearableGridPairs[i].selector.UnselectAll();
 50211                wearableGridPairs[i].selector.Select(bodyShape.id);
 50212            }
 213            else
 214            {
 750215                wearableGridPairs[i].selector.SetBodyShape(bodyShape.id);
 216            }
 217        }
 218
 50219        collectiblesItemSelector.SetBodyShape(bodyShape.id);
 50220    }
 221
 222    public void EquipWearable(WearableItem wearable)
 223    {
 978224        selectorsByCategory[wearable.data.category].Select(wearable.id);
 978225        SetWearableLoadingSpinner(wearable, true);
 978226        collectiblesItemSelector.Select(wearable.id);
 978227    }
 228
 229    public void UnequipWearable(WearableItem wearable)
 230    {
 443231        selectorsByCategory[wearable.data.category].Unselect(wearable.id);
 443232        SetWearableLoadingSpinner(wearable, false);
 443233        collectiblesItemSelector.Unselect(wearable.id);
 443234    }
 235
 236    internal void SetWearableLoadingSpinner(WearableItem wearable, bool isActive)
 237    {
 1421238        selectorsByCategory[wearable.data.category].SetWearableLoadingSpinner(wearable.id, isActive);
 1421239        collectiblesItemSelector.SetWearableLoadingSpinner(wearable.id, isActive);
 1421240        if (isActive)
 978241            wearablesWithLoadingSpinner.Add(wearable);
 242        else
 443243            wearablesWithLoadingSpinner.Remove(wearable);
 443244    }
 245
 246    internal void ClearWearablesLoadingSpinner()
 247    {
 78248        foreach (WearableItem wearable in wearablesWithLoadingSpinner)
 249        {
 19250            selectorsByCategory[wearable.data.category].SetWearableLoadingSpinner(wearable.id, false);
 19251            collectiblesItemSelector.SetWearableLoadingSpinner(wearable.id, false);
 252        }
 253
 20254        wearablesWithLoadingSpinner.Clear();
 20255    }
 256
 208257    public void SelectHairColor(Color hairColor) { hairColorSelector.Select(hairColor); }
 258
 206259    public void SelectSkinColor(Color skinColor) { skinColorSelector.Select(skinColor); }
 260
 208261    public void SelectEyeColor(Color eyesColor) { eyeColorSelector.Select(eyesColor); }
 262
 263    public void SetColors(List<Color> skinColors, List<Color> hairColors, List<Color> eyeColors)
 264    {
 46265        skinColorSelector.Populate(skinColors);
 46266        eyeColorSelector.Populate(eyeColors);
 46267        hairColorSelector.Populate(hairColors);
 46268    }
 269
 270    public void UnselectAllWearables()
 271    {
 3400272        for (int i = 0; i < wearableGridPairs.Length; i++)
 273        {
 1600274            if (wearableGridPairs[i].categoryFilter != WearableLiterals.Categories.BODY_SHAPE)
 275            {
 1500276                wearableGridPairs[i].selector.UnselectAll();
 277            }
 278        }
 279
 100280        collectiblesItemSelector.UnselectAll();
 100281    }
 282
 283    public void UpdateAvatarPreview(AvatarModel avatarModel)
 284    {
 121285        if (avatarModel?.wearables == null)
 0286            return;
 287
 121288        doneButton.interactable = false;
 121289        loadingSpinnerGameObject.SetActive(true);
 121290        characterPreviewController.UpdateModel(avatarModel,
 291            () =>
 292            {
 20293                if (doneButton != null)
 0294                    doneButton.interactable = true;
 295
 20296                loadingSpinnerGameObject?.SetActive(false);
 20297                OnAvatarAppear?.Invoke(avatarModel);
 20298                ClearWearablesLoadingSpinner();
 20299                randomizeAnimator?.SetBool(RANDOMIZE_ANIMATOR_LOADING_BOOL, false);
 0300            });
 121301    }
 302
 303    public void AddWearable(WearableItem wearableItem, int amount)
 304    {
 4050305        if (wearableItem == null)
 0306            return;
 307
 4050308        if (!selectorsByCategory.ContainsKey(wearableItem.data.category))
 309        {
 0310            Debug.LogError($"Category couldn't find selector for category: {wearableItem.data.category} ");
 0311            return;
 312        }
 313
 4050314        selectorsByCategory[wearableItem.data.category].AddItemToggle(wearableItem, amount);
 4050315        if (wearableItem.IsCollectible())
 316        {
 18317            collectiblesItemSelector.AddItemToggle(wearableItem, amount);
 318        }
 4050319    }
 320
 321    public void RemoveWearable(WearableItem wearableItem)
 322    {
 0323        if (wearableItem == null)
 0324            return;
 325
 0326        if (!selectorsByCategory.ContainsKey(wearableItem.data.category))
 327        {
 0328            Debug.LogError($"Category couldn't find selector for category: {wearableItem.data.category} ");
 0329            return;
 330        }
 331
 0332        selectorsByCategory[wearableItem.data.category].RemoveItemToggle(wearableItem.id);
 0333        if (wearableItem.IsCollectible())
 0334            collectiblesItemSelector.RemoveItemToggle(wearableItem.id);
 0335    }
 336
 337    public void RemoveAllWearables()
 338    {
 145339        using (var enumerator = selectorsByCategory.GetEnumerator())
 340        {
 2465341            while (enumerator.MoveNext())
 342            {
 2320343                enumerator.Current.Value.RemoveAllItemToggle();
 344            }
 145345        }
 346
 145347        collectiblesItemSelector.RemoveAllItemToggle();
 145348    }
 349
 350    private void OnRandomizeButton()
 351    {
 0352        OnRandomize?.Invoke();
 0353        controller.RandomizeWearables();
 0354        randomizeAnimator?.SetBool(RANDOMIZE_ANIMATOR_LOADING_BOOL, true);
 0355    }
 356
 357    private void OnDoneButton()
 358    {
 0359        doneButton.interactable = false;
 0360        characterPreviewController.TakeSnapshots(OnSnapshotsReady, OnSnapshotsFailed);
 0361    }
 362
 0363    private void OnExitButton() { OnCloseActionTriggered?.Invoke(); }
 364
 365    private void OnSnapshotsReady(Texture2D face, Texture2D face128, Texture2D face256, Texture2D body)
 366    {
 0367        doneButton.interactable = true;
 0368        controller.SaveAvatar(face, face128, face256, body);
 0369    }
 370
 0371    private void OnSnapshotsFailed() { doneButton.interactable = true; }
 372
 373    public void SetVisibility(bool visible)
 374    {
 88375        characterPreviewController.camera.enabled = visible;
 88376        avatarEditorCanvas.enabled = visible;
 88377        avatarEditorCanvasGroup.blocksRaycasts = visible;
 378
 88379        if (visible && !isOpen)
 41380            OnSetVisibility?.Invoke(visible);
 47381        else if (!visible && isOpen)
 1382            OnSetVisibility?.Invoke(visible);
 383
 88384        isOpen = visible;
 88385    }
 386
 387    public void CleanUp()
 388    {
 46389        loadingSpinnerGameObject = null;
 46390        randomizeAnimator = null;
 46391        if (wearableGridPairs != null)
 392        {
 46393            int nPairs = wearableGridPairs.Length;
 1564394            for (int i = 0; i < nPairs; i++)
 395            {
 736396                var itemSelector = wearableGridPairs[i].selector;
 736397                if (itemSelector != null)
 398                {
 736399                    itemSelector.OnItemClicked -= controller.WearableClicked;
 736400                    itemSelector.OnSellClicked -= controller.SellCollectible;
 401                }
 402            }
 403        }
 404
 46405        if (collectiblesItemSelector != null)
 406        {
 46407            collectiblesItemSelector.OnItemClicked -= controller.WearableClicked;
 46408            collectiblesItemSelector.OnSellClicked -= controller.SellCollectible;
 46409            collectiblesItemSelector.OnRetryClicked -= controller.RetryLoadOwnedWearables;
 410        }
 411
 46412        if (skinColorSelector != null)
 46413            skinColorSelector.OnColorChanged -= controller.SkinColorClicked;
 46414        if (eyeColorSelector != null)
 46415            eyeColorSelector.OnColorChanged -= controller.EyesColorClicked;
 46416        if (hairColorSelector != null)
 46417            hairColorSelector.OnColorChanged -= controller.HairColorClicked;
 418
 46419        if (this != null)
 46420            Destroy(gameObject);
 421
 46422        if (characterPreviewController != null)
 423        {
 46424            Destroy(characterPreviewController.gameObject);
 46425            characterPreviewController = null;
 426        }
 46427    }
 428
 2429    public void ShowCollectiblesLoadingSpinner(bool isActive) { collectiblesItemSelector.ShowLoading(isActive); }
 430
 2431    public void ShowCollectiblesLoadingRetry(bool isActive) { collectiblesItemSelector.ShowRetryLoading(isActive); }
 432
 0433    public void SetExitButtonActive(bool isActive) { exitButton.gameObject.SetActive(isActive); }
 434
 435    public void SetAsFullScreenMenuMode(Transform parentTransform)
 436    {
 46437        if (parentTransform == null)
 46438            return;
 439
 0440        transform.SetParent(parentTransform);
 0441        transform.localScale = Vector3.one;
 0442        SetExitButtonActive(false);
 443
 0444        RectTransform rectTransform = transform as RectTransform;
 0445        rectTransform.anchorMin = Vector2.zero;
 0446        rectTransform.anchorMax = Vector2.one;
 0447        rectTransform.pivot = new Vector2(0.5f, 0.5f);
 0448        rectTransform.localPosition = Vector2.zero;
 0449        rectTransform.offsetMax = new Vector2(0f, 50f);
 0450        rectTransform.offsetMin = Vector2.zero;
 0451    }
 452}