< Summary

Class:CarouselComponentView
Assembly:UIComponents
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/UIComponents/Scripts/Components/Carousel/CarouselComponentView.cs
Covered lines:191
Uncovered lines:53
Coverable lines:244
Total lines:649
Line coverage:78.2% (191 of 244)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
CarouselComponentView()0%110100%
Awake()0%110100%
Start()0%220100%
Configure(...)0%110100%
RefreshControl()0%22090.91%
OnScreenSizeChanged()0%110100%
Dispose()0%110100%
SetSpaceBetweenItems(...)0%2.032080%
SetTimeBetweenItems(...)0%2100%
SetAnimationTransitionTime(...)0%2100%
SetAnimationCurve(...)0%2100%
SetBackgroundColor(...)0%2.262060%
SetManualControlsActive(...)0%6.076087.5%
SetItems(...)0%6200%
SetItems(...)0%220100%
AddItem(...)0%110100%
RemoveItem(...)0%220100%
GetItems()0%2100%
ExtractItems()0%330100%
RemoveItems()0%110100%
StartCarousel(...)0%220100%
StopCarousel()0%220100%
GoToPreviousItem()0%2.062075%
ResetCarousel()0%2100%
GoToNextItem()0%2.062075%
MakeJumpFromDotsSelector(...)0%2.062075%
ConfigureManualButtonsEvents()0%330100%
CreateItem(...)0%2.012088.89%
ResizeItem(...)0%110100%
ResizeAllItems()0%5.935066.67%
DestroyInstantiatedItems()0%330100%
RunCarouselCoroutine()0%37.6518060.71%
RunRightAnimation()0%9.665042.86%
RunLeftAnimation()0%9.665042.86%
RunAnimationCoroutine()0%5.735069.23%
GenerateDotsSelector()0%660100%
SetSelectedDot(...)0%550100%
RegisterCurrentInstantiatedItems()0%6.026092.31%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/UIComponents/Scripts/Components/Carousel/CarouselComponentView.cs

#LineLine coverage
 1using DCL.Helpers;
 2using System.Collections;
 3using System.Collections.Generic;
 4using System.Linq;
 5using UnityEngine;
 6using UnityEngine.UI;
 7
 8public interface ICarouselComponentView
 9{
 10    /// <summary>
 11    /// Set the distance between carousel items.
 12    /// </summary>
 13    /// <param name="newSpace">Distance between items.</param>
 14    void SetSpaceBetweenItems(float newSpace);
 15
 16    /// <summary>
 17    /// Set the time that will be pass between carousel items.
 18    /// </summary>
 19    /// <param name="newTime">Time between items.</param>
 20    void SetTimeBetweenItems(float newTime);
 21
 22    /// <summary>
 23    /// Set the time that will be pass during the transition between items.
 24    /// </summary>
 25    /// <param name="newTime">Transition time between items.</param>
 26    void SetAnimationTransitionTime(float newTime);
 27
 28    /// <summary>
 29    /// Set the animation curve that will be used for the animation between items.
 30    /// </summary>
 31    /// <param name="newCurve">Animation curve between items.</param>
 32    void SetAnimationCurve(AnimationCurve newCurve);
 33
 34    /// <summary>
 35    /// Set the color of the carousel background.
 36    /// </summary>
 37    /// <param name="newColor">Background color.</param>
 38    void SetBackgroundColor(Color newColor);
 39
 40    /// <summary>
 41    /// Activates/Deactivates the controls to go to the next/previous item manually.
 42    /// </summary>
 43    /// <param name="isActived">True for activating the manual controls.</param>
 44    void SetManualControlsActive(bool isActived);
 45
 46    /// <summary>
 47    /// Set the items of the carousel.
 48    /// </summary>
 49    /// <param name="items">List of UI components.</param>
 50    void SetItems(List<BaseComponentView> items);
 51
 52    /// <summary>
 53    /// Creates the items of the carousel from the prefab. All previously existing items will be removed.
 54    /// </summary>
 55    /// <param name="prefab">Prefab to create items</param>
 56    /// <param name="amountOfItems">Amounts of items to be created</param>
 57    void SetItems(BaseComponentView prefab, int amountOfItems);
 58
 59    /// <summary>
 60    /// Adds a new item in the carousel.
 61    /// </summary>
 62    /// <param name="item">An UI component.</param>
 63    void AddItem(BaseComponentView item);
 64
 65    /// <summary>
 66    /// Remove an item from the carousel.
 67    /// </summary>
 68    /// <param name="item">An UI component</param>
 69    void RemoveItem(BaseComponentView item);
 70
 71    /// <summary>
 72    /// Get all the items of the carousel.
 73    /// </summary>
 74    /// <returns>The list of items.</returns>
 75    List<BaseComponentView> GetItems();
 76
 77    /// <summary>
 78    /// Extract all items out of the carousel.
 79    /// </summary>
 80    /// <returns>The list of extracted items.</returns>
 81    List<BaseComponentView> ExtractItems();
 82
 83    /// <summary>
 84    /// Remove all existing items from the carousel.
 85    /// </summary>
 86    void RemoveItems();
 87
 88    /// <summary>
 89    /// Start carousel animation.
 90    /// </summary>
 91    /// <param name="fromIndex">It specifies from where item the carousel will start.</param>
 92    /// <param name="startInmediately">True to directly execute the first transition.</param>
 93    /// <param name="direction">Set the direction of the carousel animations: right or left.</param>
 94    /// <param name="changeDirectionAfterFirstTransition">True to change the carousel direction just after the first tra
 95    /// <param name="numberOfInitialJumps">Number of jumps that will be executed in the first transition.</param>
 96    void StartCarousel(int fromIndex, bool startInmediately, CarouselDirection direction, bool changeDirectionAfterFirst
 97
 98    /// <summary>
 99    /// Stop carousel animation.
 100    /// </summary>
 101    void StopCarousel();
 102
 103    /// <summary>
 104    /// Force the carousel to show the previous item.
 105    /// </summary>
 106    void GoToPreviousItem();
 107
 108    /// <summary>
 109    /// Force the carousel to show the next item.
 110    /// </summary>
 111    void GoToNextItem();
 112
 113    /// <summary>
 114    /// Force the carousel to jump to a specific item.
 115    /// </summary>
 116    /// <param name="numberOfJumps">Number of jumps that will be executed during the transition.</param>
 117    /// <param name="direction">Direction in which to make the jumps.</param>
 118    void MakeJumpFromDotsSelector(int numberOfJumps, CarouselDirection direction);
 119}
 120
 121public enum CarouselDirection
 122{
 123    Right,
 124    Left
 125}
 126
 127public class CarouselComponentView : BaseComponentView, ICarouselComponentView, IComponentModelConfig
 128{
 129    [Header("Prefab References")]
 130    [SerializeField] internal RectTransform itemsContainer;
 131    [SerializeField] internal HorizontalLayoutGroup horizontalLayout;
 132    [SerializeField] internal ScrollRect itemsScroll;
 133    [SerializeField] internal RectTransform viewport;
 134    [SerializeField] internal Image background;
 135    [SerializeField] internal Button previousButton;
 136    [SerializeField] internal Button nextButton;
 137    [SerializeField] internal HorizontalLayoutGroup dotsSelector;
 138    [SerializeField] internal Button dotButtonTemplate;
 139    [SerializeField] internal Color dotSelectedColor;
 140    [SerializeField] internal Color dotUnselectedColor;
 141
 142    [Header("Configuration")]
 143    [SerializeField] internal CarouselComponentModel model;
 144
 173145    internal List<BaseComponentView> instantiatedItems = new List<BaseComponentView>();
 146    internal Coroutine itemsCoroutine;
 147    internal int currentItemIndex = 0;
 148    internal int currentDotIndex = 0;
 149    internal float currentFinalNormalizedPos;
 150    internal bool isInTransition = false;
 151
 152    public override void Awake()
 153    {
 73154        base.Awake();
 155
 73156        StartCoroutine(RegisterCurrentInstantiatedItems());
 73157        ConfigureManualButtonsEvents();
 73158    }
 159
 160    public override void Start()
 161    {
 3162        if (model.automaticTransition)
 3163            StartCarousel();
 3164    }
 165
 166    public void Configure(BaseComponentModel newModel)
 167    {
 1168        model = (CarouselComponentModel)newModel;
 1169        RefreshControl();
 1170    }
 171
 172    public override void RefreshControl()
 173    {
 1174        if (model == null)
 0175            return;
 176
 1177        SetSpaceBetweenItems(model.spaceBetweenItems);
 1178        SetTimeBetweenItems(model.timeBetweenItems);
 1179        SetAnimationTransitionTime(model.animationTransitionTime);
 1180        SetAnimationCurve(model.animationCurve);
 1181        SetBackgroundColor(model.backgroundColor);
 1182        SetManualControlsActive(model.showManualControls);
 1183        ResizeAllItems();
 1184        GenerateDotsSelector();
 1185    }
 186
 187    public override void OnScreenSizeChanged()
 188    {
 3189        base.OnScreenSizeChanged();
 190
 3191        ResizeAllItems();
 3192    }
 193
 194    public override void Dispose()
 195    {
 227196        base.Dispose();
 197
 227198        StopCarousel();
 227199        DestroyInstantiatedItems();
 227200    }
 201
 202    public void SetSpaceBetweenItems(float newSpace)
 203    {
 2204        model.spaceBetweenItems = newSpace;
 205
 2206        if (horizontalLayout == null)
 0207            return;
 208
 2209        horizontalLayout.spacing = newSpace;
 2210    }
 211
 0212    public void SetTimeBetweenItems(float newTime) { model.timeBetweenItems = newTime; }
 213
 0214    public void SetAnimationTransitionTime(float newTime) { model.animationTransitionTime = newTime; }
 215
 0216    public void SetAnimationCurve(AnimationCurve newCurve) { model.animationCurve = newCurve; }
 217
 218    public void SetBackgroundColor(Color newColor)
 219    {
 2220        model.backgroundColor = newColor;
 221
 2222        if (background == null)
 2223            return;
 224
 0225        background.color = newColor;
 0226    }
 227
 228    public void SetManualControlsActive(bool isActived)
 229    {
 380230        model.showManualControls = isActived;
 231
 380232        if (previousButton == null || nextButton == null)
 0233            return;
 234
 380235        int currentNumberOfItems = itemsContainer.childCount;
 380236        previousButton.gameObject.SetActive(isActived && currentNumberOfItems > 1);
 380237        nextButton.gameObject.SetActive(isActived && currentNumberOfItems > 1);
 380238        dotsSelector.gameObject.SetActive(isActived && currentNumberOfItems > 1);
 380239    }
 240
 241    public void SetItems(BaseComponentView prefab, int amountOfItems)
 242    {
 0243        DestroyInstantiatedItems();
 244
 0245        for (int i = 0; i < amountOfItems; i++)
 246        {
 0247            BaseComponentView instanciatedItem = Instantiate(prefab);
 0248            CreateItem(instanciatedItem, $"Item{i}");
 249        }
 250
 0251        SetManualControlsActive(model.showManualControls);
 0252        GenerateDotsSelector();
 0253    }
 254
 255    public void SetItems(List<BaseComponentView> items)
 256    {
 17257        DestroyInstantiatedItems();
 258
 108259        for (int i = 0; i < items.Count; i++)
 260        {
 37261            CreateItem(items[i], $"Item{i}");
 262        }
 263
 17264        SetManualControlsActive(model.showManualControls);
 17265        GenerateDotsSelector();
 17266    }
 267
 268    public void AddItem(BaseComponentView item)
 269    {
 2270        CreateItem(item, $"Item{instantiatedItems.Count}");
 2271        SetManualControlsActive(model.showManualControls);
 2272        GenerateDotsSelector();
 2273    }
 274
 275    public void RemoveItem(BaseComponentView item)
 276    {
 2277        BaseComponentView itemToRemove = instantiatedItems.FirstOrDefault(x => x == item);
 1278        if (itemToRemove != null)
 279        {
 1280            Destroy(itemToRemove.gameObject);
 1281            instantiatedItems.Remove(item);
 282        }
 283
 1284        SetManualControlsActive(model.showManualControls);
 1285        GenerateDotsSelector();
 1286    }
 287
 0288    public List<BaseComponentView> GetItems() { return instantiatedItems; }
 289
 290    public List<BaseComponentView> ExtractItems()
 291    {
 318292        List<BaseComponentView> extractedItems = new List<BaseComponentView>();
 912293        foreach (BaseComponentView item in instantiatedItems)
 294        {
 138295            if (item != null)
 138296                item.transform.SetParent(null);
 297
 138298            extractedItems.Add(item);
 299        }
 300
 318301        instantiatedItems.Clear();
 318302        SetManualControlsActive(model.showManualControls);
 303
 318304        return extractedItems;
 305    }
 306
 307    public void RemoveItems()
 308    {
 36309        DestroyInstantiatedItems();
 36310        SetManualControlsActive(model.showManualControls);
 36311    }
 312
 313    public void StartCarousel(
 314        int fromIndex = 0,
 315        bool startInmediately = false,
 316        CarouselDirection direction = CarouselDirection.Right,
 317        bool changeDirectionAfterFirstTransition = false,
 318        int numberOfInitialJumps = 1)
 319    {
 20320        StopCarousel();
 321
 20322        if (isActiveAndEnabled)
 16323            itemsCoroutine = StartCoroutine(RunCarouselCoroutine(fromIndex, startInmediately, direction, changeDirection
 20324    }
 325
 326    public void StopCarousel()
 327    {
 248328        if (itemsCoroutine == null)
 242329            return;
 330
 6331        StopCoroutine(itemsCoroutine);
 332
 6333        itemsCoroutine = null;
 6334        isInTransition = false;
 6335    }
 336
 337    public void GoToPreviousItem()
 338    {
 3339        if (isInTransition)
 0340            return;
 341
 3342        StartCarousel(
 343            fromIndex: currentItemIndex,
 344            startInmediately: true,
 345            direction: CarouselDirection.Left,
 346            changeDirectionAfterFirstTransition: true,
 347            numberOfInitialJumps: 1);
 3348    }
 349
 350    public void ResetCarousel()
 351    {
 0352        int index = 0;
 0353        SetSelectedDot(index);
 354
 0355    }
 356
 357    public void GoToNextItem()
 358    {
 5359        if (isInTransition)
 0360            return;
 361
 5362        StartCarousel(
 363            fromIndex: currentItemIndex,
 364            startInmediately: true,
 365            direction: CarouselDirection.Right,
 366            changeDirectionAfterFirstTransition: false,
 367            numberOfInitialJumps: 1);
 5368    }
 369
 370    public void MakeJumpFromDotsSelector(int numberOfJumps, CarouselDirection direction)
 371    {
 1372        if (isInTransition)
 0373            return;
 374
 1375        StartCarousel(
 376            fromIndex: currentItemIndex,
 377            startInmediately: true,
 378            direction: direction,
 379            changeDirectionAfterFirstTransition: direction == CarouselDirection.Left,
 380            numberOfInitialJumps: numberOfJumps);
 1381    }
 382
 383    internal void ConfigureManualButtonsEvents()
 384    {
 75385        if (previousButton != null)
 386        {
 75387            previousButton.onClick.RemoveAllListeners();
 75388            previousButton.onClick.AddListener(GoToPreviousItem);
 389        }
 390
 75391        if (nextButton != null)
 392        {
 75393            nextButton.onClick.RemoveAllListeners();
 75394            nextButton.onClick.AddListener(GoToNextItem);
 395        }
 75396    }
 397
 398    internal void CreateItem(BaseComponentView newItem, string name)
 399    {
 40400        if (newItem == null)
 0401            return;
 402
 40403        newItem.transform.SetParent(itemsContainer);
 40404        newItem.transform.localPosition = Vector3.zero;
 40405        newItem.transform.localScale = Vector3.one;
 40406        newItem.name = name;
 407
 40408        instantiatedItems.Add(newItem);
 409
 40410        ResizeItem((RectTransform)newItem.transform);
 40411    }
 412
 413    internal void ResizeItem(RectTransform item)
 414    {
 40415        ((RectTransform)item.transform).sizeDelta = new Vector2(viewport.rect.width, viewport.rect.height);
 416
 40417        int currentNumberOfItems = itemsContainer.childCount;
 40418        itemsContainer.offsetMin = Vector2.zero;
 40419        float extraSpace = (currentNumberOfItems - 1) * model.spaceBetweenItems;
 40420        itemsContainer.offsetMax = new Vector2(viewport.rect.width * (currentNumberOfItems - 1) + extraSpace, 0);
 40421    }
 422
 423    internal void ResizeAllItems()
 424    {
 7425        if (itemsScroll.horizontalNormalizedPosition != 0f)
 0426            itemsScroll.horizontalNormalizedPosition = 0f;
 427
 7428        if (model.automaticTransition)
 7429            StartCarousel();
 430
 14431        foreach (Transform child in itemsContainer)
 432        {
 0433            ResizeItem((RectTransform)child);
 434        }
 7435    }
 436
 437    internal void DestroyInstantiatedItems()
 438    {
 280439        List<BaseComponentView> itemsToDestroy = ExtractItems();
 820440        foreach (BaseComponentView itemToDestroy in itemsToDestroy)
 441        {
 130442            if (itemToDestroy != null)
 130443                DestroyImmediate(itemToDestroy.gameObject);
 444        }
 280445        itemsToDestroy.Clear();
 446
 280447        instantiatedItems.Clear();
 448
 280449        itemsContainer.offsetMin = Vector2.zero;
 280450        itemsContainer.offsetMax = Vector2.zero;
 280451    }
 452
 453    internal IEnumerator RunCarouselCoroutine(
 454        int fromIndex = 0,
 455        bool startInmediately = false,
 456        CarouselDirection direction = CarouselDirection.Right,
 457        bool changeDirectionAfterFirstTransition = false,
 458        int numberOfInitialJumps = 1)
 459    {
 16460        currentItemIndex = fromIndex;
 16461        SetSelectedDot(currentItemIndex);
 462
 16463        bool continueCarrousel = true;
 16464        while (gameObject.activeInHierarchy && itemsContainer.childCount > 1 && continueCarrousel)
 465        {
 6466            float elapsedTime = 0f;
 467
 6468            if (!startInmediately)
 469            {
 1470                while (elapsedTime < model.timeBetweenItems)
 471                {
 1472                    if (!model.pauseOnFocus || (model.pauseOnFocus && !isFocused))
 1473                        elapsedTime += Time.deltaTime;
 474
 1475                    yield return null;
 476                }
 477
 478            }
 479
 5480            if (instantiatedItems.Count > 0)
 481            {
 5482                if (direction == CarouselDirection.Right)
 483                {
 3484                    SetSelectedDot(currentItemIndex == (instantiatedItems.Count - 1) ? 0 : currentItemIndex + numberOfIn
 3485                    yield return RunRightAnimation(numberOfInitialJumps);
 486
 0487                    if (changeDirectionAfterFirstTransition)
 488                    {
 0489                        direction = CarouselDirection.Left;
 0490                        changeDirectionAfterFirstTransition = false;
 491                    }
 0492                    continueCarrousel = model.automaticTransition;
 0493                }
 494                else
 495                {
 2496                    SetSelectedDot(currentItemIndex == 0 ? (instantiatedItems.Count - 1) : currentItemIndex - numberOfIn
 2497                    yield return RunLeftAnimation(numberOfInitialJumps);
 498
 0499                    if (changeDirectionAfterFirstTransition)
 500                    {
 0501                        direction = CarouselDirection.Right;
 0502                        changeDirectionAfterFirstTransition = false;
 503                    }
 0504                    continueCarrousel = model.automaticTransition;
 505                }
 506            }
 507
 0508            startInmediately = false;
 0509            numberOfInitialJumps = 1;
 510        }
 10511    }
 512
 513    internal IEnumerator RunRightAnimation(int numberOfJumps = 1)
 514    {
 3515        if (currentItemIndex == instantiatedItems.Count - 1)
 516        {
 0517            currentItemIndex = 0;
 0518            yield return RunAnimationCoroutine(CarouselDirection.Left, instantiatedItems.Count - 1);
 0519        }
 520        else
 521        {
 3522            currentItemIndex += numberOfJumps;
 3523            yield return RunAnimationCoroutine(CarouselDirection.Right, numberOfJumps);
 524        }
 0525    }
 526
 527    internal IEnumerator RunLeftAnimation(int numberOfJumps = 1)
 528    {
 2529        if (currentItemIndex == 0)
 530        {
 2531            currentItemIndex = instantiatedItems.Count - 1;
 2532            yield return RunAnimationCoroutine(CarouselDirection.Right, instantiatedItems.Count - 1);
 0533        }
 534        else
 535        {
 0536            currentItemIndex -= numberOfJumps;
 0537            yield return RunAnimationCoroutine(CarouselDirection.Left, numberOfJumps);
 538        }
 0539    }
 540
 541    internal IEnumerator RunAnimationCoroutine(CarouselDirection direction, int numberOfJumps = 1)
 542    {
 5543        isInTransition = true;
 5544        float currentAnimationTime = 0f;
 5545        float initialNormalizedPos = itemsScroll.horizontalNormalizedPosition;
 546
 5547        if (direction == CarouselDirection.Right)
 5548            currentFinalNormalizedPos = initialNormalizedPos + ((float)numberOfJumps / (instantiatedItems.Count - 1));
 549        else
 0550            currentFinalNormalizedPos = initialNormalizedPos - ((float)numberOfJumps / (instantiatedItems.Count - 1));
 551
 5552        while (currentAnimationTime <= model.animationTransitionTime)
 553        {
 5554            itemsScroll.horizontalNormalizedPosition = Mathf.Clamp01(Mathf.Lerp(
 555                initialNormalizedPos,
 556                currentFinalNormalizedPos,
 557                model.animationCurve.Evaluate(currentAnimationTime / model.animationTransitionTime)));
 558
 5559            currentAnimationTime += Time.deltaTime;
 560
 5561            yield return null;
 562        }
 563
 0564        itemsScroll.horizontalNormalizedPosition = currentFinalNormalizedPos;
 0565        isInTransition = false;
 0566    }
 567
 568    internal void GenerateDotsSelector()
 569    {
 26570        List<GameObject> dotsToRemove = new List<GameObject>();
 122571        foreach (Transform child in dotsSelector.transform)
 572        {
 35573            if (child.gameObject == dotButtonTemplate.gameObject)
 574                continue;
 575
 9576            dotsToRemove.Add(child.gameObject);
 577        }
 578
 70579        foreach (GameObject dotToRemove in dotsToRemove)
 580        {
 9581            Utils.SafeDestroy(dotToRemove);
 582        }
 583
 140584        for (int i = 0; i < itemsContainer.childCount; i++)
 585        {
 44586            Button newDotButton = Instantiate(dotButtonTemplate, dotsSelector.transform);
 44587            newDotButton.gameObject.SetActive(true);
 44588            newDotButton.onClick.AddListener(() =>
 589            {
 0590                int dotButtonIndex = newDotButton.transform.GetSiblingIndex() - 1;
 0591                if (dotButtonIndex != currentDotIndex)
 592                {
 0593                    MakeJumpFromDotsSelector(
 594                        Mathf.Abs(dotButtonIndex - currentDotIndex),
 595                        dotButtonIndex > currentDotIndex ? CarouselDirection.Right : CarouselDirection.Left);
 596                }
 0597            });
 598        }
 599
 26600        SetSelectedDot(0);
 26601    }
 602
 603    internal void SetSelectedDot(int index)
 604    {
 48605        int currentIndex = 0;
 48606        currentDotIndex = -1;
 346607        foreach (Transform child in dotsSelector.transform)
 608        {
 125609            if (child.gameObject == dotButtonTemplate.gameObject)
 610                continue;
 611
 77612            if (currentIndex == index)
 613            {
 34614                child.GetComponent<Image>().color = dotSelectedColor;
 34615                child.transform.localScale = Vector3.one * 1.5f;
 34616                currentDotIndex = index;
 34617            }
 618            else
 619            {
 43620                child.GetComponent<Image>().color = dotUnselectedColor;
 43621                child.transform.localScale = Vector3.one;
 622            }
 623
 77624            currentIndex++;
 625        }
 48626    }
 627
 628    internal IEnumerator RegisterCurrentInstantiatedItems()
 629    {
 73630        instantiatedItems.Clear();
 631
 344632        foreach (Transform child in itemsContainer)
 633        {
 99634            BaseComponentView existingItem = child.GetComponent<BaseComponentView>();
 99635            if (existingItem != null)
 99636                instantiatedItems.Add(existingItem);
 637            else
 0638                Destroy(child.gameObject);
 639        }
 640
 641        // In the first loading, before calculating the size of the current items, it is needed to wait for a frame in o
 642        // allow time for the carousel viewport to get its final size to be able to execute the 'ResizeAllItems' functio
 73643        yield return null;
 644
 3645        ResizeAllItems();
 3646        SetManualControlsActive(model.showManualControls);
 3647        GenerateDotsSelector();
 3648    }
 649}