< Summary

Class:GridContainerComponentView
Assembly:UIComponents
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/UIComponents/Scripts/Components/GridContainer/GridContainerComponentView.cs
Covered lines:139
Uncovered lines:57
Coverable lines:196
Total lines:516
Line coverage:70.9% (139 of 196)
Covered branches:0
Total branches:0
Covered methods:28
Total methods:32
Method coverage:87.5% (28 of 32)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
GridContainerComponentView()0%110100%
Awake()0%110100%
Show(...)0%6200%
Hide(...)0%6200%
Configure(...)0%110100%
RefreshControl()0%3.13077.78%
OnScreenSizeChanged()0%110100%
Dispose()0%110100%
SetConstraint(...)0%2.032080%
SetConstraintCount(...)0%2.032080%
SetItemSizeToContainerAdaptation(...)0%110100%
SetItemSize(...)0%12.2812087.5%
CalculateAutoSize(...)0%72800%
CalculateHorizontalSizeForFixedColumnConstraint(...)0%220100%
CalculateHorizontalSizeForFixedRowConstraint(...)0%110100%
CalculateHorizontalSizeForFlexibleConstraint(...)0%10.45040%
SetSpaceBetweenItems(...)0%2.032080%
SetMinWidthForFlexibleItems(...)0%110100%
SetItems(...)0%6200%
SetItems(...)0%220100%
AddItemWithResize(...)0%110100%
SetItemSizeForModel()0%110100%
AddItem(...)0%110100%
RemoveItem(...)0%220100%
GetItems()0%110100%
ExtractItems()0%330100%
RemoveItems()0%330100%
CreateItem(...)0%2.012087.5%
ResizeGridContainer()0%660100%
RegisterCurrentInstantiatedItems()0%4.014090.91%

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 item size and resize grid container with respect to the current model.
 41    /// </summary>
 42    void SetItemSizeForModel();
 43
 44    /// <summary>
 45    /// Set the space between child items.
 46    /// </summary>
 47    /// <param name="newSpace">Space between children.</param>
 48    void SetSpaceBetweenItems(Vector2 newSpace);
 49
 50    /// <summary>
 51    /// Set the minimum width for the items when constraint is set to flexible.
 52    /// </summary>
 53    /// <param name="minWidthForFlexibleItems">Min item width.</param>
 54    void SetMinWidthForFlexibleItems(float minWidthForFlexibleItems);
 55
 56    /// <summary>
 57    /// Creates the items of the grid from the prefab. All previously existing items will be removed.
 58    /// </summary>
 59    /// <param name="prefab">Prefab to create items</param>
 60    /// <param name="amountOfItems">Amounts of items to be created</param>
 61    void SetItems(BaseComponentView prefab, int amountOfItems);
 62
 63    /// <summary>
 64    /// Set the items of the grid. All previously existing items will be removed.
 65    /// </summary>
 66    /// <param name="items">List of UI components.</param>
 67    void SetItems(List<BaseComponentView> items);
 68
 69    /// <summary>
 70    /// Adds a new item in the grid.
 71    /// </summary>
 72    /// <param name="item">An UI component.</param>
 73    void AddItem(BaseComponentView item);
 74
 75    /// <summary>
 76    /// Adds a new item in the grid and resize the grid.
 77    /// </summary>
 78    /// <param name="item">An UI component.</param>
 79    void AddItemWithResize(BaseComponentView item);
 80
 81    /// <summary>
 82    /// Remove an item from the grid.
 83    /// </summary>
 84    /// <param name="item">An UI component</param>
 85    void RemoveItem(BaseComponentView item);
 86
 87    /// <summary>
 88    /// Get all the items of the grid.
 89    /// </summary>
 90    /// <returns>List of items.</returns>
 91    List<BaseComponentView> GetItems();
 92
 93    /// <summary>
 94    /// Extract all items out of the grid.
 95    /// </summary>
 96    /// <returns>The list of extracted items.</returns>
 97    List<BaseComponentView> ExtractItems();
 98
 99    /// <summary>
 100    /// Remove all existing items from the grid.
 101    /// </summary>
 102    void RemoveItems();
 103}
 104
 105public class GridContainerComponentView : BaseComponentView, IGridContainerComponentView, IComponentModelConfig<GridCont
 106{
 107    [Header("Prefab References")]
 108    [SerializeField] internal GridLayoutGroup gridLayoutGroup;
 109    [SerializeField] internal RectTransform externalParentToAdaptSize;
 110
 111    [Header("Configuration")]
 112    [SerializeField] internal GridContainerComponentModel model;
 113
 2871114    internal List<BaseComponentView> instantiatedItems = new List<BaseComponentView>();
 115
 1936116    public int currentItemsPerRow { get; internal set; }
 117
 118    public override void Awake()
 119    {
 1394120        base.Awake();
 121
 1394122        RegisterCurrentInstantiatedItems();
 1394123    }
 124
 125    public override void Show(bool instant = false)
 126    {
 0127        base.Show(instant);
 128
 0129        if (instant)
 0130            gameObject.SetActive(true);
 0131    }
 132
 133    public override void Hide(bool instant = false)
 134    {
 0135        base.Hide(instant);
 136
 0137        if (instant)
 0138            gameObject.SetActive(false);
 0139    }
 140
 141    public void Configure(GridContainerComponentModel newModel)
 142    {
 1143        model = newModel;
 1144        RefreshControl();
 1145    }
 146
 147    public override void RefreshControl()
 148    {
 2149        if (model == null)
 0150            return;
 151
 152        //We only do this if we are from editor, this is done because the editor doesn't call awake method
 2153        if (!Application.isPlaying)
 0154            RegisterCurrentInstantiatedItems();
 155
 2156        SetConstraint(model.constraint);
 2157        SetItemSize(model.itemSize);
 2158        SetConstraintCount(model.constraintCount);
 2159        SetSpaceBetweenItems(model.spaceBetweenItems);
 2160    }
 161
 162    public override void OnScreenSizeChanged()
 163    {
 21164        base.OnScreenSizeChanged();
 165
 21166        SetItemSize(model.itemSize);
 21167        SetConstraintCount(model.constraintCount);
 21168    }
 169
 170    public override void Dispose()
 171    {
 2939172        base.Dispose();
 173
 2939174        RemoveItems();
 2939175    }
 176
 177    public void SetConstraint(Constraint newConstraint)
 178    {
 7179        model.constraint = newConstraint;
 180
 7181        if (gridLayoutGroup == null)
 0182            return;
 183
 7184        gridLayoutGroup.constraint = newConstraint;
 7185    }
 186
 187    public void SetConstraintCount(int newConstraintCount)
 188    {
 1418189        model.constraintCount = newConstraintCount;
 190
 1418191        if (gridLayoutGroup == null)
 0192            return;
 193
 1418194        gridLayoutGroup.constraintCount = newConstraintCount;
 1418195    }
 196
 197    public void SetItemSizeToContainerAdaptation(bool adaptItemSizeToContainer)
 198    {
 1199        model.adaptHorizontallyItemSizeToContainer = adaptItemSizeToContainer;
 1200        SetItemSize(model.itemSize);
 1201    }
 202
 203    public void SetItemSize(Vector2 newItemSize)
 204    {
 13191205        Vector2 newSizeToApply = newItemSize;
 206
 13191207        if (instantiatedItems.Count > 0)
 208        {
 1938209            if (model.adaptVerticallyItemSizeToContainer && model.adaptHorizontallyItemSizeToContainer)
 210            {
 0211                CalculateAutoSize(out newSizeToApply);
 212            }
 1938213            else if (model.adaptVerticallyItemSizeToContainer)
 214            {
 215                //TODO: We need to implement this functionality. Nobody is using it
 216                //      Please implement it if needed
 0217                throw new Exception("Not implemented yet! Please implement the functionality");
 218            }
 1938219            else if (model.adaptHorizontallyItemSizeToContainer)
 220            {
 1754221                switch (model.constraint)
 222                {
 223                    case Constraint.FixedColumnCount:
 1750224                        CalculateHorizontalSizeForFixedColumnConstraint(out newSizeToApply);
 1750225                        break;
 226                    case Constraint.FixedRowCount:
 2227                        CalculateHorizontalSizeForFixedRowConstraint(out newSizeToApply);
 2228                        break;
 229                    case Constraint.Flexible:
 2230                        CalculateHorizontalSizeForFlexibleConstraint(out newSizeToApply, newItemSize);
 2231                        break;
 232                }
 233            }
 234            else
 235            {
 184236                switch (model.constraint)
 237                {
 238                    case Constraint.FixedColumnCount:
 239                    case Constraint.Flexible:
 176240                        currentItemsPerRow = model.constraintCount;
 176241                        break;
 242                    case Constraint.FixedRowCount:
 8243                        currentItemsPerRow = (int)Mathf.Ceil((float)instantiatedItems.Count / model.constraintCount);
 244                        break;
 245                }
 246            }
 247        }
 248
 13191249        model.itemSize = newSizeToApply;
 250
 13191251        if (gridLayoutGroup == null)
 0252            return;
 253
 13191254        gridLayoutGroup.cellSize = newSizeToApply;
 255
 13191256        ResizeGridContainer();
 13191257    }
 258
 259    private void CalculateAutoSize(out Vector2 newSizeToApply)
 260    {
 0261        float height = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.height : ((RectTransform)trans
 0262        float width = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.width : ((RectTransform)transfo
 263
 0264        int amountsOfHorizontalItemsPerRow =  instantiatedItems.Count / model.constraintCount;
 0265        int amountsOfVerticalItemsPerColumn =  instantiatedItems.Count / amountsOfHorizontalItemsPerRow;
 266
 0267        float extraSpaceToRemoveX = model.spaceBetweenItems.x * (amountsOfHorizontalItemsPerRow - 1);
 0268        float extraSpaceToRemoveY = model.spaceBetweenItems.y * (amountsOfVerticalItemsPerColumn - 1);
 269
 0270        float itemWidth = model.recommendedWidthForFlexibleItems;
 0271        float itemHeight = model.recommendedHeightForFlexibleItems;
 272
 0273        if (itemWidth * amountsOfHorizontalItemsPerRow + extraSpaceToRemoveX >= width)
 0274            itemWidth = (width - extraSpaceToRemoveX) / amountsOfHorizontalItemsPerRow;
 275
 0276        if (itemWidth < model.minWidthForFlexibleItems)
 0277            itemWidth = model.minWidthForFlexibleItems;
 278
 0279        if (itemHeight * amountsOfVerticalItemsPerColumn + extraSpaceToRemoveY >= height)
 0280            itemHeight = (height - extraSpaceToRemoveY) / amountsOfVerticalItemsPerColumn;
 281
 0282        if (itemHeight < model.minHeightForFlexibleItems)
 0283            itemHeight = model.minHeightForFlexibleItems;
 284
 0285        if (model.sameHeightAndWidhtFlexibleItem)
 286        {
 0287            float minValue = Mathf.Min(itemHeight, itemWidth);
 0288            itemHeight = minValue;
 0289            itemWidth = minValue;
 290        }
 291
 0292        newSizeToApply = new Vector2(
 293            itemWidth,
 294            itemHeight);
 295
 0296        currentItemsPerRow = model.constraintCount;
 0297    }
 298
 299    private void CalculateHorizontalSizeForFixedColumnConstraint(out Vector2 newSizeToApply)
 300    {
 1750301        float width = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.width : ((RectTransform)transfo
 1750302        float extraSpaceToRemove = (model.spaceBetweenItems.x * (model.constraintCount - 1)) / model.constraintCount;
 303
 1750304        newSizeToApply = new Vector2(
 305            (width / model.constraintCount) - extraSpaceToRemove,
 306            model.itemSize.y);
 307
 1750308        currentItemsPerRow = model.constraintCount;
 1750309    }
 310
 311    private void CalculateHorizontalSizeForFixedRowConstraint(out Vector2 newSizeToApply)
 312    {
 2313        float height = ((RectTransform)transform).rect.height;
 2314        float extraSpaceToRemove = (model.spaceBetweenItems.y / (model.constraintCount / 2f));
 315
 2316        newSizeToApply = new Vector2(
 317            model.itemSize.x,
 318            (height / model.constraintCount) - extraSpaceToRemove);
 319
 2320        currentItemsPerRow = (int)Mathf.Ceil((float)instantiatedItems.Count / model.constraintCount);
 2321    }
 322
 323    private void CalculateHorizontalSizeForFlexibleConstraint(out Vector2 newSizeToApply, Vector2 newItemSize)
 324    {
 2325        newSizeToApply = newItemSize;
 326
 2327        float width = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.width : ((RectTransform)transfo
 2328        int numberOfPossibleItems = (int)(width / model.minWidthForFlexibleItems);
 329
 2330        SetConstraint(Constraint.FixedColumnCount);
 331
 2332        if (numberOfPossibleItems > 0)
 333        {
 0334            for (int numColumnsToTry = 1; numColumnsToTry <= numberOfPossibleItems; numColumnsToTry++)
 335            {
 0336                SetConstraintCount(numColumnsToTry);
 0337                SetItemSize(model.itemSize);
 0338                currentItemsPerRow = numColumnsToTry;
 339
 0340                if (model.itemSize.x < model.minWidthForFlexibleItems)
 341                {
 0342                    SetConstraintCount(numColumnsToTry - 1);
 0343                    SetItemSize(model.itemSize);
 0344                    currentItemsPerRow = numColumnsToTry - 1;
 0345                    break;
 346                }
 347
 0348                newSizeToApply = model.itemSize;
 349            }
 350        }
 351        else
 352        {
 2353            newSizeToApply = new Vector2(model.minWidthForFlexibleItems, newSizeToApply.y);
 354        }
 355
 2356        SetConstraint(Constraint.Flexible);
 2357    }
 358
 359    public void SetSpaceBetweenItems(Vector2 newSpace)
 360    {
 1950361        model.spaceBetweenItems = newSpace;
 362
 1950363        if (gridLayoutGroup == null)
 0364            return;
 365
 1950366        gridLayoutGroup.spacing = newSpace;
 1950367    }
 368
 369    public void SetMinWidthForFlexibleItems(float minWidthForFlexibleItems)
 370    {
 1371        model.minWidthForFlexibleItems = minWidthForFlexibleItems;
 1372        SetItemSize(model.itemSize);
 1373    }
 374
 375    public void SetItems(BaseComponentView prefab, int amountOfItems)
 376    {
 0377        RemoveItems();
 378
 0379        for (int i = 0; i < amountOfItems; i++)
 380        {
 0381            BaseComponentView instanciatedItem = Instantiate(prefab);
 0382            CreateItem(instanciatedItem, $"Item{i}");
 383        }
 384
 0385        SetItemSize(model.itemSize);
 0386    }
 387
 388    public void SetItems(List<BaseComponentView> items)
 389    {
 12390        RemoveItems();
 391
 62392        for (int i = 0; i < items.Count; i++)
 393        {
 19394            CreateItem(items[i], $"Item{i}");
 395        }
 396
 12397        SetItemSize(model.itemSize);
 12398    }
 399
 400    public void AddItemWithResize(BaseComponentView item)
 401    {
 1765402        CreateItem(item, $"Item{instantiatedItems.Count}");
 1765403        SetItemSize(model.itemSize);
 1765404    }
 405
 406    public void SetItemSizeForModel() =>
 4407        SetItemSize(model.itemSize);
 408
 409    public void AddItem(BaseComponentView item) =>
 61410        CreateItem(item, $"Item{instantiatedItems.Count}");
 411
 412    public void RemoveItem(BaseComponentView item)
 413    {
 8414        BaseComponentView itemToRemove = instantiatedItems.FirstOrDefault(x => x == item);
 4415        if (itemToRemove != null)
 416        {
 4417            Destroy(itemToRemove.gameObject);
 4418            instantiatedItems.Remove(item);
 419        }
 420
 4421        SetItemSize(model.itemSize);
 4422    }
 423
 491424    public List<BaseComponentView> GetItems() { return instantiatedItems; }
 425
 426    public List<BaseComponentView> ExtractItems()
 427    {
 5022428        List<BaseComponentView> extractedItems = new List<BaseComponentView>();
 12004429        foreach (BaseComponentView item in instantiatedItems)
 430        {
 980431            if (item != null)
 974432                item.transform.SetParent(null);
 433
 980434            extractedItems.Add(item);
 435        }
 436
 5022437        instantiatedItems.Clear();
 438
 5022439        SetItemSize(model.itemSize);
 440
 5022441        return extractedItems;
 442    }
 443
 444    public void RemoveItems()
 445    {
 4959446        List<BaseComponentView> itemsToDestroy = ExtractItems();
 11762447        foreach (BaseComponentView itemToDestroy in itemsToDestroy)
 448        {
 922449            if (itemToDestroy != null)
 916450                DestroyImmediate(itemToDestroy.gameObject);
 451        }
 4959452        itemsToDestroy.Clear();
 453
 4959454        instantiatedItems.Clear();
 455
 4959456        SetItemSize(model.itemSize);
 4959457    }
 458
 459    internal void CreateItem(BaseComponentView newItem, string name)
 460    {
 1846461        if (newItem == null)
 0462            return;
 463
 1846464        newItem.transform.SetParent(transform);
 1846465        newItem.transform.localPosition = Vector3.zero;
 1846466        newItem.transform.localScale = Vector3.one;
 1846467        newItem.name = name;
 468
 1846469        instantiatedItems.Add(newItem);
 1846470    }
 471
 472    private void ResizeGridContainer()
 473    {
 13191474        int currentNumberOfItems = transform.childCount;
 475
 13191476        if (currentNumberOfItems == 0)
 477        {
 11244478            ((RectTransform)transform).sizeDelta = Vector2.zero;
 11244479            return;
 480        }
 481
 1947482        if (model.constraint == Constraint.FixedColumnCount)
 483        {
 1927484            int numRows = (int)Mathf.Ceil((float)currentNumberOfItems / model.constraintCount);
 1927485            ((RectTransform)transform).sizeDelta = new Vector2(
 486                model.adaptHorizontallyItemSizeToContainer ? ((RectTransform)transform).sizeDelta.x : (model.constraintC
 487                (numRows * model.itemSize.y) + (model.spaceBetweenItems.y * (numRows - 1)));
 488        }
 20489        else if (model.constraint == Constraint.FixedRowCount)
 490        {
 16491            int numCols = (int)Mathf.Ceil((float)currentNumberOfItems / model.constraintCount);
 16492            ((RectTransform)transform).sizeDelta = new Vector2(
 493                (numCols * model.itemSize.x) + (model.spaceBetweenItems.x * (numCols - 1)),
 494                model.adaptHorizontallyItemSizeToContainer ? ((RectTransform)transform).sizeDelta.y : (model.constraintC
 495        }
 496
 1947497        SetSpaceBetweenItems(model.spaceBetweenItems);
 1947498    }
 499
 500    private void RegisterCurrentInstantiatedItems()
 501    {
 1394502        instantiatedItems.Clear();
 503
 3096504        foreach (Transform child in transform)
 505        {
 154506            BaseComponentView existingItem = child.GetComponent<BaseComponentView>();
 154507            if (existingItem != null)
 154508                instantiatedItems.Add(existingItem);
 509            else
 0510                DestroyImmediate(child.gameObject);
 511        }
 512
 1394513        SetItemSize(model.itemSize);
 1394514        SetConstraintCount(model.constraintCount);
 1394515    }
 516}