< Summary

Class:GridContainerComponentView
Assembly:UIComponents
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/UIComponents/Scripts/Components/GridContainer/GridContainerComponentView.cs
Covered lines:163
Uncovered lines:26
Coverable lines:189
Total lines:483
Line coverage:86.2% (163 of 189)
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.13077.78%
OnScreenSizeChanged()0%110100%
Dispose()0%110100%
SetConstraint(...)0%2.032080%
SetConstraintCount(...)0%2.032080%
SetItemSizeToContainerAdaptation(...)0%110100%
SetItemSize(...)0%12.0712092%
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%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 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<GridCont
 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
 1154103    internal List<BaseComponentView> instantiatedItems = new List<BaseComponentView>();
 104
 0105    public int currentItemsPerRow { get; internal set; }
 106
 107    public override void Awake()
 108    {
 479109        base.Awake();
 110
 479111        RegisterCurrentInstantiatedItems();
 479112    }
 113
 114    public void Configure(GridContainerComponentModel newModel)
 115    {
 7116        model = newModel;
 7117        RefreshControl();
 7118    }
 119
 120    public override void RefreshControl()
 121    {
 9122        if (model == null)
 0123            return;
 124
 125        //We only do this if we are from editor, this is done because the editor doesn't call awake method
 9126        if (!Application.isPlaying)
 0127            RegisterCurrentInstantiatedItems();
 128
 9129        SetConstraint(model.constraint);
 9130        SetItemSize(model.itemSize);
 9131        SetConstraintCount(model.constraintCount);
 9132        SetSpaceBetweenItems(model.spaceBetweenItems);
 9133    }
 134
 135    public override void OnScreenSizeChanged()
 136    {
 1137        base.OnScreenSizeChanged();
 138
 1139        SetItemSize(model.itemSize);
 1140        SetConstraintCount(model.constraintCount);
 1141    }
 142
 143    public override void Dispose()
 144    {
 1063145        base.Dispose();
 146
 1063147        RemoveItems();
 1063148    }
 149
 150    public void SetConstraint(Constraint newConstraint)
 151    {
 14152        model.constraint = newConstraint;
 153
 14154        if (gridLayoutGroup == null)
 0155            return;
 156
 14157        gridLayoutGroup.constraint = newConstraint;
 14158    }
 159
 160    public void SetConstraintCount(int newConstraintCount)
 161    {
 490162        model.constraintCount = newConstraintCount;
 163
 490164        if (gridLayoutGroup == null)
 0165            return;
 166
 490167        gridLayoutGroup.constraintCount = newConstraintCount;
 490168    }
 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    {
 5267178        Vector2 newSizeToApply = newItemSize;
 179
 5267180        if (instantiatedItems.Count > 0)
 181        {
 1648182            if (model.adaptVerticallyItemSizeToContainer && model.adaptHorizontallyItemSizeToContainer)
 183            {
 15184                CalculateAutoSize(out newSizeToApply);
 15185            }
 1633186            else if (model.adaptVerticallyItemSizeToContainer)
 187            {
 188                //TODO: We need to implement this functionality. Nobody is using it
 189                //      Please implement it if needed
 0190                throw new Exception("Not implemented yet! Please implement the functionality");
 191            }
 1633192            else if (model.adaptHorizontallyItemSizeToContainer)
 193            {
 599194                switch (model.constraint)
 195                {
 196                    case Constraint.FixedColumnCount:
 595197                        CalculateHorizontalSizeForFixedColumnConstraint(out newSizeToApply);
 595198                        break;
 199                    case Constraint.FixedRowCount:
 2200                        CalculateHorizontalSizeForFixedRowConstraint(out newSizeToApply);
 2201                        break;
 202                    case Constraint.Flexible:
 2203                        CalculateHorizontalSizeForFlexibleConstraint(out newSizeToApply, newItemSize);
 2204                        break;
 205                }
 206            }
 207            else
 208            {
 1034209                switch (model.constraint)
 210                {
 211                    case Constraint.FixedColumnCount:
 212                    case Constraint.Flexible:
 1026213                        currentItemsPerRow = model.constraintCount;
 1026214                        break;
 215                    case Constraint.FixedRowCount:
 8216                        currentItemsPerRow = (int)Mathf.Ceil((float)instantiatedItems.Count / model.constraintCount);
 217                        break;
 218                }
 219            }
 220        }
 221
 5267222        model.itemSize = newSizeToApply;
 223
 5267224        if (gridLayoutGroup == null)
 0225            return;
 226
 5267227        gridLayoutGroup.cellSize = newSizeToApply;
 228
 5267229        ResizeGridContainer();
 5267230    }
 231
 232    internal void CalculateAutoSize(out Vector2 newSizeToApply)
 233    {
 15234        float height = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.height : ((RectTransform)trans
 15235        float width = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.width : ((RectTransform)transfo
 236
 15237        int amountsOfHorizontalItemsPerRow =  instantiatedItems.Count / model.constraintCount;
 15238        int amountsOfVerticalItemsPerColumn =  instantiatedItems.Count / amountsOfHorizontalItemsPerRow;
 239
 15240        float extraSpaceToRemoveX = model.spaceBetweenItems.x * (amountsOfHorizontalItemsPerRow - 1);
 15241        float extraSpaceToRemoveY = model.spaceBetweenItems.y * (amountsOfVerticalItemsPerColumn - 1);
 242
 15243        float itemWidth = model.recommendedWidthForFlexibleItems;
 15244        float itemHeight = model.recommendedHeightForFlexibleItems;
 245
 15246        if (itemWidth * amountsOfHorizontalItemsPerRow + extraSpaceToRemoveX >= width)
 0247            itemWidth = (width - extraSpaceToRemoveX) / amountsOfHorizontalItemsPerRow;
 248
 15249        if (itemWidth < model.minWidthForFlexibleItems)
 0250            itemWidth = model.minWidthForFlexibleItems;
 251
 15252        if (itemHeight * amountsOfVerticalItemsPerColumn + extraSpaceToRemoveY >= height)
 0253            itemHeight = (height - extraSpaceToRemoveY) / amountsOfVerticalItemsPerColumn;
 254
 15255        if (itemHeight < model.minHeightForFlexibleItems)
 0256            itemHeight = model.minHeightForFlexibleItems;
 257
 15258        if (model.sameHeightAndWidhtFlexibleItem)
 259        {
 15260            float minValue = Mathf.Min(itemHeight, itemWidth);
 15261            itemHeight = minValue;
 15262            itemWidth = minValue;
 263        }
 264
 15265        newSizeToApply = new Vector2(
 266            itemWidth,
 267            itemHeight);
 268
 15269        currentItemsPerRow = model.constraintCount;
 15270    }
 271
 272    internal void CalculateHorizontalSizeForFixedColumnConstraint(out Vector2 newSizeToApply)
 273    {
 595274        float width = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.width : ((RectTransform)transfo
 595275        float extraSpaceToRemove = (model.spaceBetweenItems.x * (model.constraintCount - 1)) / model.constraintCount;
 276
 595277        newSizeToApply = new Vector2(
 278            (width / model.constraintCount) - extraSpaceToRemove,
 279            model.itemSize.y);
 280
 595281        currentItemsPerRow = model.constraintCount;
 595282    }
 283
 284    internal void CalculateHorizontalSizeForFixedRowConstraint(out Vector2 newSizeToApply)
 285    {
 2286        float height = ((RectTransform)transform).rect.height;
 2287        float extraSpaceToRemove = (model.spaceBetweenItems.y / (model.constraintCount / 2f));
 288
 2289        newSizeToApply = new Vector2(
 290            model.itemSize.x,
 291            (height / model.constraintCount) - extraSpaceToRemove);
 292
 2293        currentItemsPerRow = (int)Mathf.Ceil((float)instantiatedItems.Count / model.constraintCount);
 2294    }
 295
 296    internal void CalculateHorizontalSizeForFlexibleConstraint(out Vector2 newSizeToApply, Vector2 newItemSize)
 297    {
 2298        newSizeToApply = newItemSize;
 299
 2300        float width = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.width : ((RectTransform)transfo
 2301        int numberOfPossibleItems = (int)(width / model.minWidthForFlexibleItems);
 302
 2303        SetConstraint(Constraint.FixedColumnCount);
 304
 2305        if (numberOfPossibleItems > 0)
 306        {
 0307            for (int numColumnsToTry = 1; numColumnsToTry <= numberOfPossibleItems; numColumnsToTry++)
 308            {
 0309                SetConstraintCount(numColumnsToTry);
 0310                SetItemSize(model.itemSize);
 0311                currentItemsPerRow = numColumnsToTry;
 312
 0313                if (model.itemSize.x < model.minWidthForFlexibleItems)
 314                {
 0315                    SetConstraintCount(numColumnsToTry - 1);
 0316                    SetItemSize(model.itemSize);
 0317                    currentItemsPerRow = numColumnsToTry - 1;
 0318                    break;
 319                }
 320
 0321                newSizeToApply = model.itemSize;
 322            }
 0323        }
 324        else
 325        {
 2326            newSizeToApply = new Vector2(model.minWidthForFlexibleItems, newSizeToApply.y);
 327        }
 328
 2329        SetConstraint(Constraint.Flexible);
 2330    }
 331
 332    public void SetSpaceBetweenItems(Vector2 newSpace)
 333    {
 1992334        model.spaceBetweenItems = newSpace;
 335
 1992336        if (gridLayoutGroup == null)
 0337            return;
 338
 1992339        gridLayoutGroup.spacing = newSpace;
 1992340    }
 341
 342    public void SetMinWidthForFlexibleItems(float minWidthForFlexibleItems)
 343    {
 1344        model.minWidthForFlexibleItems = minWidthForFlexibleItems;
 1345        SetItemSize(model.itemSize);
 1346    }
 347
 348    public void SetItems(BaseComponentView prefab, int amountOfItems)
 349    {
 2350        RemoveItems();
 351
 20352        for (int i = 0; i < amountOfItems; i++)
 353        {
 8354            BaseComponentView instanciatedItem = Instantiate(prefab);
 8355            CreateItem(instanciatedItem, $"Item{i}");
 356        }
 357
 2358        SetItemSize(model.itemSize);
 2359    }
 360
 361    public void SetItems(List<BaseComponentView> items)
 362    {
 18363        RemoveItems();
 364
 98365        for (int i = 0; i < items.Count; i++)
 366        {
 31367            CreateItem(items[i], $"Item{i}");
 368        }
 369
 18370        SetItemSize(model.itemSize);
 18371    }
 372
 373    public void AddItem(BaseComponentView item)
 374    {
 1411375        CreateItem(item, $"Item{instantiatedItems.Count}");
 1411376        SetItemSize(model.itemSize);
 1411377    }
 378
 379    public void RemoveItem(BaseComponentView item)
 380    {
 8381        BaseComponentView itemToRemove = instantiatedItems.FirstOrDefault(x => x == item);
 4382        if (itemToRemove != null)
 383        {
 4384            Destroy(itemToRemove.gameObject);
 4385            instantiatedItems.Remove(item);
 386        }
 387
 4388        SetItemSize(model.itemSize);
 4389    }
 390
 0391    public List<BaseComponentView> GetItems() { return instantiatedItems; }
 392
 393    public List<BaseComponentView> ExtractItems()
 394    {
 1775395        List<BaseComponentView> extractedItems = new List<BaseComponentView>();
 7964396        foreach (BaseComponentView item in instantiatedItems)
 397        {
 2207398            if (item != null)
 2202399                item.transform.SetParent(null);
 400
 2207401            extractedItems.Add(item);
 402        }
 403
 1775404        instantiatedItems.Clear();
 405
 1775406        SetItemSize(model.itemSize);
 407
 1775408        return extractedItems;
 409    }
 410
 411    public void RemoveItems()
 412    {
 1560413        List<BaseComponentView> itemsToDestroy = ExtractItems();
 5634414        foreach (BaseComponentView itemToDestroy in itemsToDestroy)
 415        {
 1257416            if (itemToDestroy != null)
 1252417                DestroyImmediate(itemToDestroy.gameObject);
 418        }
 1560419        itemsToDestroy.Clear();
 420
 1560421        instantiatedItems.Clear();
 422
 1560423        SetItemSize(model.itemSize);
 1560424    }
 425
 426    internal void CreateItem(BaseComponentView newItem, string name)
 427    {
 1451428        if (newItem == null)
 0429            return;
 430
 1451431        newItem.transform.SetParent(transform);
 1451432        newItem.transform.localPosition = Vector3.zero;
 1451433        newItem.transform.localScale = Vector3.one;
 1451434        newItem.name = name;
 435
 1451436        instantiatedItems.Add(newItem);
 1451437    }
 438
 439    internal void ResizeGridContainer()
 440    {
 5267441        int currentNumberOfItems = transform.childCount;
 442
 5267443        if (currentNumberOfItems == 0)
 444        {
 3285445            ((RectTransform)transform).sizeDelta = Vector2.zero;
 3285446            return;
 447        }
 448
 1982449        if (model.constraint == Constraint.FixedColumnCount)
 450        {
 1013451            int numRows = (int)Mathf.Ceil((float)currentNumberOfItems / model.constraintCount);
 1013452            ((RectTransform)transform).sizeDelta = new Vector2(
 453                model.adaptHorizontallyItemSizeToContainer ? ((RectTransform)transform).sizeDelta.x : (model.constraintC
 454                (numRows * model.itemSize.y) + (model.spaceBetweenItems.y * (numRows - 1)));
 1013455        }
 969456        else if (model.constraint == Constraint.FixedRowCount)
 457        {
 35458            int numCols = (int)Mathf.Ceil((float)currentNumberOfItems / model.constraintCount);
 35459            ((RectTransform)transform).sizeDelta = new Vector2(
 460                (numCols * model.itemSize.x) + (model.spaceBetweenItems.x * (numCols - 1)),
 461                model.adaptHorizontallyItemSizeToContainer ? ((RectTransform)transform).sizeDelta.y : (model.constraintC
 462        }
 463
 1982464        SetSpaceBetweenItems(model.spaceBetweenItems);
 1982465    }
 466
 467    internal void RegisterCurrentInstantiatedItems()
 468    {
 479469        instantiatedItems.Clear();
 470
 2952471        foreach (Transform child in transform)
 472        {
 997473            BaseComponentView existingItem = child.GetComponent<BaseComponentView>();
 997474            if (existingItem != null)
 997475                instantiatedItems.Add(existingItem);
 476            else
 0477                DestroyImmediate(child.gameObject);
 478        }
 479
 479480        SetItemSize(model.itemSize);
 479481        SetConstraintCount(model.constraintCount);
 479482    }
 483}