< Summary

Class:GridContainerComponentView
Assembly:UIComponents
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/UIComponents/Scripts/Components/GridContainer/GridContainerComponentView.cs
Covered lines:156
Uncovered lines:25
Coverable lines:181
Total lines:470
Line coverage:86.1% (156 of 181)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
GridContainerComponentView()0%110100%
Awake()0%110100%
Configure(...)0%110100%
RefreshControl()0%3.013088.89%
OnScreenSizeChanged()0%110100%
Dispose()0%110100%
SetConstraint(...)0%2.032080%
SetConstraintCount(...)0%2.032080%
SetItemSizeToContainerAdaptation(...)0%110100%
SetItemSize(...)0%11.0711091.67%
CalculateAutoSize(...)0%8.348082.61%
CalculateHorizontalSizeForFixedColumnConstraint(...)0%220100%
CalculateHorizontalSizeForFixedRowConstraint(...)0%110100%
CalculateHorizontalSizeForFlexibleConstraint(...)0%10.935038.1%
SetSpaceBetweenItems(...)0%2.032080%
SetMinWidthForFlexibleItems(...)0%110100%
SetItems(...)0%220100%
SetItems(...)0%220100%
AddItem(...)0%110100%
RemoveItem(...)0%220100%
GetItems()0%2100%
ExtractItems()0%220100%
RemoveItems()0%330100%
CreateItem(...)0%2.012087.5%
ResizeGridContainer()0%660100%
RegisterCurrentInstantiatedItems()0%4.024090%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/UIComponents/Scripts/Components/GridContainer/GridContainerComponentView.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using UnityEngine;
 5using UnityEngine.UI;
 6using static UnityEngine.UI.GridLayoutGroup;
 7
 8public interface IGridContainerComponentView
 9{
 10    /// <summary>
 11    /// Number of items per row that fit with the current grid configuration.
 12    /// </summary>
 13    int currentItemsPerRow { get; }
 14
 15    /// <summary>
 16    /// Set the type of constraint of the grid.
 17    /// </summary>
 18    /// <param name="newConstraint">Type of constraint.</param>
 19    void SetConstraint(Constraint newConstraint);
 20
 21    /// <summary>
 22    /// Set the number of columns/rows of the grid depending on the type of constraint set.
 23    /// </summary>
 24    /// <param name="newConstraintCount">Number of columns or rows.</param>
 25    void SetConstraintCount(int newConstraintCount);
 26
 27    /// <summary>
 28    /// Set the item size adaptation to the container.
 29    /// </summary>
 30    /// <param name="adaptItemSizeToContainer">True for activate the size adaptation.</param>
 31    void SetItemSizeToContainerAdaptation(bool adaptItemSizeToContainer);
 32
 33    /// <summary>
 34    /// Set the size of each child item.
 35    /// </summary>
 36    /// <param name="newItemSize">Size of each child.</param>
 37    void SetItemSize(Vector2 newItemSize);
 38
 39    /// <summary>
 40    /// Set the space between child items.
 41    /// </summary>
 42    /// <param name="newSpace">Space between children.</param>
 43    void SetSpaceBetweenItems(Vector2 newSpace);
 44
 45    /// <summary>
 46    /// Set the minimum width for the items when constraint is set to flexible.
 47    /// </summary>
 48    /// <param name="minWidthForFlexibleItems">Min item width.</param>
 49    void SetMinWidthForFlexibleItems(float minWidthForFlexibleItems);
 50
 51    /// <summary>
 52    /// Creates the items of the grid from the prefab. All previously existing items will be removed.
 53    /// </summary>
 54    /// <param name="prefab">Prefab to create items</param>
 55    /// <param name="amountOfItems">Amounts of items to be created</param>
 56    void SetItems(BaseComponentView prefab, int amountOfItems);
 57
 58    /// <summary>
 59    /// Set the items of the grid. All previously existing items will be removed.
 60    /// </summary>
 61    /// <param name="items">List of UI components.</param>
 62    void SetItems(List<BaseComponentView> items);
 63
 64    /// <summary>
 65    /// Adds a new item in the grid.
 66    /// </summary>
 67    /// <param name="item">An UI component.</param>
 68    void AddItem(BaseComponentView item);
 69
 70    /// <summary>
 71    /// Remove an item from the grid.
 72    /// </summary>
 73    /// <param name="item">An UI component</param>
 74    void RemoveItem(BaseComponentView item);
 75
 76    /// <summary>
 77    /// Get all the items of the grid.
 78    /// </summary>
 79    /// <returns>List of items.</returns>
 80    List<BaseComponentView> GetItems();
 81
 82    /// <summary>
 83    /// Extract all items out of the grid.
 84    /// </summary>
 85    /// <returns>The list of extracted items.</returns>
 86    List<BaseComponentView> ExtractItems();
 87
 88    /// <summary>
 89    /// Remove all existing items from the grid.
 90    /// </summary>
 91    void RemoveItems();
 92}
 93
 94public class GridContainerComponentView : BaseComponentView, IGridContainerComponentView, IComponentModelConfig
 95{
 96    [Header("Prefab References")]
 97    [SerializeField] internal GridLayoutGroup gridLayoutGroup;
 98    [SerializeField] internal RectTransform externalParentToAdaptSize;
 99
 100    [Header("Configuration")]
 101    [SerializeField] internal GridContainerComponentModel model;
 102
 272103    internal List<BaseComponentView> instantiatedItems = new List<BaseComponentView>();
 104
 0105    public int currentItemsPerRow { get; internal set; }
 106
 107    public override void Awake()
 108    {
 136109        base.Awake();
 110
 136111        RegisterCurrentInstantiatedItems();
 136112    }
 113
 114    public void Configure(BaseComponentModel newModel)
 115    {
 3116        model = (GridContainerComponentModel)newModel;
 3117        RefreshControl();
 3118    }
 119
 120    public override void RefreshControl()
 121    {
 3122        if (model == null)
 0123            return;
 124
 125        //We only do this if we don't have items, this is done because the editor doesn't call awake method
 3126        if(instantiatedItems.Count == 0)
 1127            RegisterCurrentInstantiatedItems();
 128
 3129        SetConstraint(model.constraint);
 3130        SetItemSize(model.itemSize);
 3131        SetConstraintCount(model.constraintCount);
 3132        SetSpaceBetweenItems(model.spaceBetweenItems);
 3133    }
 134
 135    public override void OnScreenSizeChanged()
 136    {
 149137        base.OnScreenSizeChanged();
 138
 149139        SetItemSize(model.itemSize);
 149140        SetConstraintCount(model.constraintCount);
 149141    }
 142
 143    public override void Dispose()
 144    {
 441145        base.Dispose();
 146
 441147        RemoveItems();
 441148    }
 149
 150    public void SetConstraint(Constraint newConstraint)
 151    {
 6152        model.constraint = newConstraint;
 153
 6154        if (gridLayoutGroup == null)
 0155            return;
 156
 6157        gridLayoutGroup.constraint = newConstraint;
 6158    }
 159
 160    public void SetConstraintCount(int newConstraintCount)
 161    {
 153162        model.constraintCount = newConstraintCount;
 163
 153164        if (gridLayoutGroup == null)
 0165            return;
 166
 153167        gridLayoutGroup.constraintCount = newConstraintCount;
 153168    }
 169
 170    public void SetItemSizeToContainerAdaptation(bool adaptItemSizeToContainer)
 171    {
 1172        model.adaptHorizontallyItemSizeToContainer = adaptItemSizeToContainer;
 1173        SetItemSize(model.itemSize);
 1174    }
 175
 176    public void SetItemSize(Vector2 newItemSize)
 177    {
 181178        Vector2 newSizeToApply = newItemSize;
 179
 181180        if (model.adaptVerticallyItemSizeToContainer  && model.adaptHorizontallyItemSizeToContainer)
 181        {
 10182           CalculateAutoSize(out newSizeToApply);
 10183        }
 171184        else if (model.adaptVerticallyItemSizeToContainer)
 185        {
 186            //TODO: We need to implement this functionality. Nobody is using it
 187            //      Please implement it if needed
 0188            throw new Exception("Not implemented yet! Please implement the functionality");
 189        }
 171190        else if (model.adaptHorizontallyItemSizeToContainer)
 191        {
 72192            switch (model.constraint)
 193            {
 194                case Constraint.FixedColumnCount:
 70195                    CalculateHorizontalSizeForFixedColumnConstraint(out newSizeToApply);
 70196                    break;
 197                case Constraint.FixedRowCount:
 1198                    CalculateHorizontalSizeForFixedRowConstraint(out newSizeToApply);
 1199                    break;
 200                case Constraint.Flexible:
 1201                    CalculateHorizontalSizeForFlexibleConstraint(out newSizeToApply, newItemSize);
 1202                    break;
 203            }
 204        }
 205        else
 206        {
 99207            switch (model.constraint)
 208            {
 209                case Constraint.FixedColumnCount:
 210                case Constraint.Flexible:
 49211                    currentItemsPerRow = model.constraintCount;
 49212                    break;
 213                case Constraint.FixedRowCount:
 50214                    currentItemsPerRow = (int)Mathf.Ceil((float)instantiatedItems.Count / model.constraintCount);
 215                    break;
 216            }
 217        }
 218
 181219        model.itemSize = newSizeToApply;
 220
 181221        if (gridLayoutGroup == null)
 0222            return;
 223
 181224        gridLayoutGroup.cellSize = newSizeToApply;
 225
 181226        ResizeGridContainer();
 181227    }
 228
 229    internal void CalculateAutoSize(out Vector2 newSizeToApply)
 230    {
 10231        float height = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.height : ((RectTransform)trans
 10232        float width = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.width : ((RectTransform)transfo
 233
 10234        int amountsOfHorizontalItemsPerRow =  instantiatedItems.Count / model.constraintCount;
 10235        int amountsOfVerticalItemsPerColumn =  instantiatedItems.Count / amountsOfHorizontalItemsPerRow;
 236
 10237        float extraSpaceToRemoveX = model.spaceBetweenItems.x * (amountsOfHorizontalItemsPerRow - 1);
 10238        float extraSpaceToRemoveY = model.spaceBetweenItems.y * (amountsOfVerticalItemsPerColumn - 1);
 239
 10240        float itemWidth = model.recommendedWidthForFlexibleItems;
 10241        float itemHeight = model.recommendedHeightForFlexibleItems;
 242
 10243        if (itemWidth * amountsOfHorizontalItemsPerRow + extraSpaceToRemoveX >= width)
 0244            itemWidth = width / amountsOfHorizontalItemsPerRow - extraSpaceToRemoveX;
 245
 10246        if (itemWidth < model.minWidthForFlexibleItems)
 0247            itemWidth = model.minWidthForFlexibleItems;
 248
 10249        if (itemHeight * amountsOfVerticalItemsPerColumn + extraSpaceToRemoveY >= height)
 0250            itemHeight = height / amountsOfVerticalItemsPerColumn - extraSpaceToRemoveY;
 251
 10252        if (itemHeight < model.minHeightForFlexibleItems)
 0253            itemHeight = model.minHeightForFlexibleItems;
 254
 10255        if (model.sameHeightAndWidhtFlexibleItem)
 256        {
 10257            float minValue = Mathf.Min(itemHeight, itemWidth);
 10258            itemHeight = minValue;
 10259            itemWidth = minValue;
 260        }
 261
 10262        newSizeToApply = new Vector2(
 263            itemWidth,
 264            itemHeight);
 265
 10266        currentItemsPerRow = model.constraintCount;
 10267    }
 268
 269    internal void CalculateHorizontalSizeForFixedColumnConstraint(out Vector2 newSizeToApply)
 270    {
 70271        float width = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.width : ((RectTransform)transfo
 70272        float extraSpaceToRemove = (model.spaceBetweenItems.x * (model.constraintCount - 1)) / model.constraintCount;
 273
 70274        newSizeToApply = new Vector2(
 275            (width / model.constraintCount) - extraSpaceToRemove,
 276            model.itemSize.y);
 277
 70278        currentItemsPerRow = model.constraintCount;
 70279    }
 280
 281    internal void CalculateHorizontalSizeForFixedRowConstraint(out Vector2 newSizeToApply)
 282    {
 1283        float height = ((RectTransform)transform).rect.height;
 1284        float extraSpaceToRemove = (model.spaceBetweenItems.y / (model.constraintCount / 2f));
 285
 1286        newSizeToApply = new Vector2(
 287            model.itemSize.x,
 288            (height / model.constraintCount) - extraSpaceToRemove);
 289
 1290        currentItemsPerRow = (int)Mathf.Ceil((float)instantiatedItems.Count / model.constraintCount);
 1291    }
 292
 293    internal void CalculateHorizontalSizeForFlexibleConstraint(out Vector2 newSizeToApply, Vector2 newItemSize)
 294    {
 1295        newSizeToApply = newItemSize;
 296
 1297        float width = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.width : ((RectTransform)transfo
 1298        int numberOfPossibleItems = (int)(width / model.minWidthForFlexibleItems);
 299
 1300        SetConstraint(Constraint.FixedColumnCount);
 301
 1302        if (numberOfPossibleItems > 0)
 303        {
 0304            for (int numColumnsToTry = 1; numColumnsToTry <= numberOfPossibleItems; numColumnsToTry++)
 305            {
 0306                SetConstraintCount(numColumnsToTry);
 0307                SetItemSize(model.itemSize);
 0308                currentItemsPerRow = numColumnsToTry;
 309
 0310                if (model.itemSize.x < model.minWidthForFlexibleItems)
 311                {
 0312                    SetConstraintCount(numColumnsToTry - 1);
 0313                    SetItemSize(model.itemSize);
 0314                    currentItemsPerRow = numColumnsToTry - 1;
 0315                    break;
 316                }
 317
 0318                newSizeToApply = model.itemSize;
 319            }
 0320        }
 321        else
 322        {
 1323            newSizeToApply = new Vector2(model.minWidthForFlexibleItems, newSizeToApply.y);
 324        }
 325
 1326        SetConstraint(Constraint.Flexible);
 1327    }
 328
 329    public void SetSpaceBetweenItems(Vector2 newSpace)
 330    {
 190331        model.spaceBetweenItems = newSpace;
 332
 190333        if (gridLayoutGroup == null)
 0334            return;
 335
 190336        gridLayoutGroup.spacing = newSpace;
 190337    }
 338
 339    public void SetMinWidthForFlexibleItems(float minWidthForFlexibleItems)
 340    {
 1341        model.minWidthForFlexibleItems = minWidthForFlexibleItems;
 1342        SetItemSize(model.itemSize);
 1343    }
 344
 345    public void SetItems(BaseComponentView prefab, int amountOfItems)
 346    {
 2347        RemoveItems();
 348
 20349        for (int i = 0; i < amountOfItems; i++)
 350        {
 8351            BaseComponentView instanciatedItem = Instantiate(prefab);
 8352            CreateItem(instanciatedItem, $"Item{i}");
 353        }
 354
 2355        SetItemSize(model.itemSize);
 2356    }
 357
 358    public void SetItems(List<BaseComponentView> items)
 359    {
 8360        RemoveItems();
 361
 50362        for (int i = 0; i < items.Count; i++)
 363        {
 17364            CreateItem(items[i], $"Item{i}");
 365        }
 366
 8367        SetItemSize(model.itemSize);
 8368    }
 369
 370    public void AddItem(BaseComponentView item)
 371    {
 9372        CreateItem(item, $"Item{instantiatedItems.Count}");
 9373        SetItemSize(model.itemSize);
 9374    }
 375
 376    public void RemoveItem(BaseComponentView item)
 377    {
 4378        BaseComponentView itemToRemove = instantiatedItems.FirstOrDefault(x => x == item);
 2379        if (itemToRemove != null)
 380        {
 2381            Destroy(itemToRemove.gameObject);
 2382            instantiatedItems.Remove(item);
 383        }
 384
 2385        SetItemSize(model.itemSize);
 2386    }
 387
 0388    public List<BaseComponentView> GetItems() { return instantiatedItems; }
 389
 390    public List<BaseComponentView> ExtractItems()
 391    {
 84392        List<BaseComponentView> extractedItems = new List<BaseComponentView>();
 196393        foreach (BaseComponentView item in instantiatedItems)
 394        {
 14395            item.transform.SetParent(null);
 14396            extractedItems.Add(item);
 397        }
 398
 84399        instantiatedItems.Clear();
 400
 84401        return extractedItems;
 402    }
 403
 404    public void RemoveItems()
 405    {
 1694406        foreach (Transform child in transform)
 407        {
 261408            Destroy(child.gameObject);
 409        }
 410
 586411        instantiatedItems.Clear();
 586412    }
 413
 414    internal void CreateItem(BaseComponentView newItem, string name)
 415    {
 35416        if (newItem == null)
 0417            return;
 418
 35419        newItem.transform.SetParent(transform);
 35420        newItem.transform.localPosition = Vector3.zero;
 35421        newItem.transform.localScale = Vector3.one;
 35422        newItem.name = name;
 423
 35424        instantiatedItems.Add(newItem);
 35425    }
 426
 427    internal void ResizeGridContainer()
 428    {
 318429        int currentNumberOfItems = transform.childCount;
 430
 318431        if (currentNumberOfItems == 0)
 432        {
 132433            ((RectTransform)transform).sizeDelta = Vector2.zero;
 132434            return;
 435        }
 436
 186437        if (model.constraint == Constraint.FixedColumnCount)
 438        {
 166439            int numRows = (int)Mathf.Ceil((float)currentNumberOfItems / model.constraintCount);
 166440            ((RectTransform)transform).sizeDelta = new Vector2(
 441                model.adaptHorizontallyItemSizeToContainer ? ((RectTransform)transform).sizeDelta.x : (model.constraintC
 442                (numRows * model.itemSize.y) + (model.spaceBetweenItems.y * (numRows - 1)));
 166443        }
 20444        else if (model.constraint == Constraint.FixedRowCount)
 445        {
 20446            int numCols = (int)Mathf.Ceil((float)currentNumberOfItems / model.constraintCount);
 20447            ((RectTransform)transform).sizeDelta = new Vector2(
 448                (numCols * model.itemSize.x) + (model.spaceBetweenItems.x * (numCols - 1)),
 449                model.adaptHorizontallyItemSizeToContainer ? ((RectTransform)transform).sizeDelta.y : (model.constraintC
 450        }
 451
 186452        SetSpaceBetweenItems(model.spaceBetweenItems);
 186453    }
 454
 455    internal void RegisterCurrentInstantiatedItems()
 456    {
 137457        instantiatedItems.Clear();
 458
 466459        foreach (Transform child in transform)
 460        {
 96461            BaseComponentView existingItem = child.GetComponent<BaseComponentView>();
 96462            if (existingItem != null)
 96463                instantiatedItems.Add(existingItem);
 464            else
 0465                DestroyImmediate(child.gameObject);
 466        }
 467
 137468        ResizeGridContainer();
 137469    }
 470}