< 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:49
Coverable lines:188
Total lines:500
Line coverage:73.9% (139 of 188)
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.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
 1157114    internal List<BaseComponentView> instantiatedItems = new List<BaseComponentView>();
 115
 1843116    public int currentItemsPerRow { get; internal set; }
 117
 118    public override void Awake()
 119    {
 921120        base.Awake();
 121
 921122        RegisterCurrentInstantiatedItems();
 921123    }
 124
 125    public void Configure(GridContainerComponentModel newModel)
 126    {
 1127        model = newModel;
 1128        RefreshControl();
 1129    }
 130
 131    public override void RefreshControl()
 132    {
 3133        if (model == null)
 0134            return;
 135
 136        //We only do this if we are from editor, this is done because the editor doesn't call awake method
 3137        if (!Application.isPlaying)
 0138            RegisterCurrentInstantiatedItems();
 139
 3140        SetConstraint(model.constraint);
 3141        SetItemSize(model.itemSize);
 3142        SetConstraintCount(model.constraintCount);
 3143        SetSpaceBetweenItems(model.spaceBetweenItems);
 3144    }
 145
 146    public override void OnScreenSizeChanged()
 147    {
 55148        base.OnScreenSizeChanged();
 149
 55150        SetItemSize(model.itemSize);
 55151        SetConstraintCount(model.constraintCount);
 55152    }
 153
 154    public override void Dispose()
 155    {
 2218156        base.Dispose();
 157
 2218158        RemoveItems();
 2218159    }
 160
 161    public void SetConstraint(Constraint newConstraint)
 162    {
 8163        model.constraint = newConstraint;
 164
 8165        if (gridLayoutGroup == null)
 0166            return;
 167
 8168        gridLayoutGroup.constraint = newConstraint;
 8169    }
 170
 171    public void SetConstraintCount(int newConstraintCount)
 172    {
 980173        model.constraintCount = newConstraintCount;
 174
 980175        if (gridLayoutGroup == null)
 0176            return;
 177
 980178        gridLayoutGroup.constraintCount = newConstraintCount;
 980179    }
 180
 181    public void SetItemSizeToContainerAdaptation(bool adaptItemSizeToContainer)
 182    {
 1183        model.adaptHorizontallyItemSizeToContainer = adaptItemSizeToContainer;
 1184        SetItemSize(model.itemSize);
 1185    }
 186
 187    public void SetItemSize(Vector2 newItemSize)
 188    {
 9113189        Vector2 newSizeToApply = newItemSize;
 190
 9113191        if (instantiatedItems.Count > 0)
 192        {
 1845193            if (model.adaptVerticallyItemSizeToContainer && model.adaptHorizontallyItemSizeToContainer)
 194            {
 0195                CalculateAutoSize(out newSizeToApply);
 196            }
 1845197            else if (model.adaptVerticallyItemSizeToContainer)
 198            {
 199                //TODO: We need to implement this functionality. Nobody is using it
 200                //      Please implement it if needed
 0201                throw new Exception("Not implemented yet! Please implement the functionality");
 202            }
 1845203            else if (model.adaptHorizontallyItemSizeToContainer)
 204            {
 811205                switch (model.constraint)
 206                {
 207                    case Constraint.FixedColumnCount:
 807208                        CalculateHorizontalSizeForFixedColumnConstraint(out newSizeToApply);
 807209                        break;
 210                    case Constraint.FixedRowCount:
 2211                        CalculateHorizontalSizeForFixedRowConstraint(out newSizeToApply);
 2212                        break;
 213                    case Constraint.Flexible:
 2214                        CalculateHorizontalSizeForFlexibleConstraint(out newSizeToApply, newItemSize);
 2215                        break;
 216                }
 217            }
 218            else
 219            {
 1034220                switch (model.constraint)
 221                {
 222                    case Constraint.FixedColumnCount:
 223                    case Constraint.Flexible:
 1026224                        currentItemsPerRow = model.constraintCount;
 1026225                        break;
 226                    case Constraint.FixedRowCount:
 8227                        currentItemsPerRow = (int)Mathf.Ceil((float)instantiatedItems.Count / model.constraintCount);
 228                        break;
 229                }
 230            }
 231        }
 232
 9113233        model.itemSize = newSizeToApply;
 234
 9113235        if (gridLayoutGroup == null)
 0236            return;
 237
 9113238        gridLayoutGroup.cellSize = newSizeToApply;
 239
 9113240        ResizeGridContainer();
 9113241    }
 242
 243    private void CalculateAutoSize(out Vector2 newSizeToApply)
 244    {
 0245        float height = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.height : ((RectTransform)trans
 0246        float width = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.width : ((RectTransform)transfo
 247
 0248        int amountsOfHorizontalItemsPerRow =  instantiatedItems.Count / model.constraintCount;
 0249        int amountsOfVerticalItemsPerColumn =  instantiatedItems.Count / amountsOfHorizontalItemsPerRow;
 250
 0251        float extraSpaceToRemoveX = model.spaceBetweenItems.x * (amountsOfHorizontalItemsPerRow - 1);
 0252        float extraSpaceToRemoveY = model.spaceBetweenItems.y * (amountsOfVerticalItemsPerColumn - 1);
 253
 0254        float itemWidth = model.recommendedWidthForFlexibleItems;
 0255        float itemHeight = model.recommendedHeightForFlexibleItems;
 256
 0257        if (itemWidth * amountsOfHorizontalItemsPerRow + extraSpaceToRemoveX >= width)
 0258            itemWidth = (width - extraSpaceToRemoveX) / amountsOfHorizontalItemsPerRow;
 259
 0260        if (itemWidth < model.minWidthForFlexibleItems)
 0261            itemWidth = model.minWidthForFlexibleItems;
 262
 0263        if (itemHeight * amountsOfVerticalItemsPerColumn + extraSpaceToRemoveY >= height)
 0264            itemHeight = (height - extraSpaceToRemoveY) / amountsOfVerticalItemsPerColumn;
 265
 0266        if (itemHeight < model.minHeightForFlexibleItems)
 0267            itemHeight = model.minHeightForFlexibleItems;
 268
 0269        if (model.sameHeightAndWidhtFlexibleItem)
 270        {
 0271            float minValue = Mathf.Min(itemHeight, itemWidth);
 0272            itemHeight = minValue;
 0273            itemWidth = minValue;
 274        }
 275
 0276        newSizeToApply = new Vector2(
 277            itemWidth,
 278            itemHeight);
 279
 0280        currentItemsPerRow = model.constraintCount;
 0281    }
 282
 283    private void CalculateHorizontalSizeForFixedColumnConstraint(out Vector2 newSizeToApply)
 284    {
 807285        float width = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.width : ((RectTransform)transfo
 807286        float extraSpaceToRemove = (model.spaceBetweenItems.x * (model.constraintCount - 1)) / model.constraintCount;
 287
 807288        newSizeToApply = new Vector2(
 289            (width / model.constraintCount) - extraSpaceToRemove,
 290            model.itemSize.y);
 291
 807292        currentItemsPerRow = model.constraintCount;
 807293    }
 294
 295    private void CalculateHorizontalSizeForFixedRowConstraint(out Vector2 newSizeToApply)
 296    {
 2297        float height = ((RectTransform)transform).rect.height;
 2298        float extraSpaceToRemove = (model.spaceBetweenItems.y / (model.constraintCount / 2f));
 299
 2300        newSizeToApply = new Vector2(
 301            model.itemSize.x,
 302            (height / model.constraintCount) - extraSpaceToRemove);
 303
 2304        currentItemsPerRow = (int)Mathf.Ceil((float)instantiatedItems.Count / model.constraintCount);
 2305    }
 306
 307    private void CalculateHorizontalSizeForFlexibleConstraint(out Vector2 newSizeToApply, Vector2 newItemSize)
 308    {
 2309        newSizeToApply = newItemSize;
 310
 2311        float width = externalParentToAdaptSize != null ? externalParentToAdaptSize.rect.width : ((RectTransform)transfo
 2312        int numberOfPossibleItems = (int)(width / model.minWidthForFlexibleItems);
 313
 2314        SetConstraint(Constraint.FixedColumnCount);
 315
 2316        if (numberOfPossibleItems > 0)
 317        {
 0318            for (int numColumnsToTry = 1; numColumnsToTry <= numberOfPossibleItems; numColumnsToTry++)
 319            {
 0320                SetConstraintCount(numColumnsToTry);
 0321                SetItemSize(model.itemSize);
 0322                currentItemsPerRow = numColumnsToTry;
 323
 0324                if (model.itemSize.x < model.minWidthForFlexibleItems)
 325                {
 0326                    SetConstraintCount(numColumnsToTry - 1);
 0327                    SetItemSize(model.itemSize);
 0328                    currentItemsPerRow = numColumnsToTry - 1;
 0329                    break;
 330                }
 331
 0332                newSizeToApply = model.itemSize;
 333            }
 334        }
 335        else
 336        {
 2337            newSizeToApply = new Vector2(model.minWidthForFlexibleItems, newSizeToApply.y);
 338        }
 339
 2340        SetConstraint(Constraint.Flexible);
 2341    }
 342
 343    public void SetSpaceBetweenItems(Vector2 newSpace)
 344    {
 2242345        model.spaceBetweenItems = newSpace;
 346
 2242347        if (gridLayoutGroup == null)
 0348            return;
 349
 2242350        gridLayoutGroup.spacing = newSpace;
 2242351    }
 352
 353    public void SetMinWidthForFlexibleItems(float minWidthForFlexibleItems)
 354    {
 1355        model.minWidthForFlexibleItems = minWidthForFlexibleItems;
 1356        SetItemSize(model.itemSize);
 1357    }
 358
 359    public void SetItems(BaseComponentView prefab, int amountOfItems)
 360    {
 0361        RemoveItems();
 362
 0363        for (int i = 0; i < amountOfItems; i++)
 364        {
 0365            BaseComponentView instanciatedItem = Instantiate(prefab);
 0366            CreateItem(instanciatedItem, $"Item{i}");
 367        }
 368
 0369        SetItemSize(model.itemSize);
 0370    }
 371
 372    public void SetItems(List<BaseComponentView> items)
 373    {
 12374        RemoveItems();
 375
 62376        for (int i = 0; i < items.Count; i++)
 377        {
 19378            CreateItem(items[i], $"Item{i}");
 379        }
 380
 12381        SetItemSize(model.itemSize);
 12382    }
 383
 384    public void AddItemWithResize(BaseComponentView item)
 385    {
 1407386        CreateItem(item, $"Item{instantiatedItems.Count}");
 1407387        SetItemSize(model.itemSize);
 1407388    }
 389
 390    public void SetItemSizeForModel() =>
 4391        SetItemSize(model.itemSize);
 392
 393    public void AddItem(BaseComponentView item) =>
 56394        CreateItem(item, $"Item{instantiatedItems.Count}");
 395
 396    public void RemoveItem(BaseComponentView item)
 397    {
 8398        BaseComponentView itemToRemove = instantiatedItems.FirstOrDefault(x => x == item);
 4399        if (itemToRemove != null)
 400        {
 4401            Destroy(itemToRemove.gameObject);
 4402            instantiatedItems.Remove(item);
 403        }
 404
 4405        SetItemSize(model.itemSize);
 4406    }
 407
 4935408    public List<BaseComponentView> GetItems() { return instantiatedItems; }
 409
 410    public List<BaseComponentView> ExtractItems()
 411    {
 3466412        List<BaseComponentView> extractedItems = new List<BaseComponentView>();
 11798413        foreach (BaseComponentView item in instantiatedItems)
 414        {
 2433415            if (item != null)
 2428416                item.transform.SetParent(null);
 417
 2433418            extractedItems.Add(item);
 419        }
 420
 3466421        instantiatedItems.Clear();
 422
 3466423        SetItemSize(model.itemSize);
 424
 3466425        return extractedItems;
 426    }
 427
 428    public void RemoveItems()
 429    {
 3233430        List<BaseComponentView> itemsToDestroy = ExtractItems();
 9352431        foreach (BaseComponentView itemToDestroy in itemsToDestroy)
 432        {
 1443433            if (itemToDestroy != null)
 1438434                DestroyImmediate(itemToDestroy.gameObject);
 435        }
 3233436        itemsToDestroy.Clear();
 437
 3233438        instantiatedItems.Clear();
 439
 3233440        SetItemSize(model.itemSize);
 3233441    }
 442
 443    internal void CreateItem(BaseComponentView newItem, string name)
 444    {
 1483445        if (newItem == null)
 0446            return;
 447
 1483448        newItem.transform.SetParent(transform);
 1483449        newItem.transform.localPosition = Vector3.zero;
 1483450        newItem.transform.localScale = Vector3.one;
 1483451        newItem.name = name;
 452
 1483453        instantiatedItems.Add(newItem);
 1483454    }
 455
 456    private void ResizeGridContainer()
 457    {
 9113458        int currentNumberOfItems = transform.childCount;
 459
 9113460        if (currentNumberOfItems == 0)
 461        {
 6875462            ((RectTransform)transform).sizeDelta = Vector2.zero;
 6875463            return;
 464        }
 465
 2238466        if (model.constraint == Constraint.FixedColumnCount)
 467        {
 1288468            int numRows = (int)Mathf.Ceil((float)currentNumberOfItems / model.constraintCount);
 1288469            ((RectTransform)transform).sizeDelta = new Vector2(
 470                model.adaptHorizontallyItemSizeToContainer ? ((RectTransform)transform).sizeDelta.x : (model.constraintC
 471                (numRows * model.itemSize.y) + (model.spaceBetweenItems.y * (numRows - 1)));
 472        }
 950473        else if (model.constraint == Constraint.FixedRowCount)
 474        {
 16475            int numCols = (int)Mathf.Ceil((float)currentNumberOfItems / model.constraintCount);
 16476            ((RectTransform)transform).sizeDelta = new Vector2(
 477                (numCols * model.itemSize.x) + (model.spaceBetweenItems.x * (numCols - 1)),
 478                model.adaptHorizontallyItemSizeToContainer ? ((RectTransform)transform).sizeDelta.y : (model.constraintC
 479        }
 480
 2238481        SetSpaceBetweenItems(model.spaceBetweenItems);
 2238482    }
 483
 484    private void RegisterCurrentInstantiatedItems()
 485    {
 921486        instantiatedItems.Clear();
 487
 4208488        foreach (Transform child in transform)
 489        {
 1183490            BaseComponentView existingItem = child.GetComponent<BaseComponentView>();
 1183491            if (existingItem != null)
 1183492                instantiatedItems.Add(existingItem);
 493            else
 0494                DestroyImmediate(child.gameObject);
 495        }
 496
 921497        SetItemSize(model.itemSize);
 921498        SetConstraintCount(model.constraintCount);
 921499    }
 500}