| | 1 | | using DCL.Controllers; |
| | 2 | | using DCL.Helpers; |
| | 3 | | using DCL.Models; |
| | 4 | | using System.Collections; |
| | 5 | | using System.Collections.Generic; |
| | 6 | | using UnityEngine; |
| | 7 | | using UnityEngine.Assertions; |
| | 8 | | using UnityEngine.UI; |
| | 9 | | using Decentraland.Sdk.Ecs6; |
| | 10 | | using MainScripts.DCL.Components; |
| | 11 | |
|
| | 12 | | namespace DCL.Components |
| | 13 | | { |
| | 14 | | public class UIContainerStack : UIShape<UIContainerRectReferencesContainer, UIContainerStack.Model> |
| | 15 | | { |
| | 16 | | [System.Serializable] |
| | 17 | | public new class Model : UIShape.Model |
| | 18 | | { |
| 45 | 19 | | public Color color = Color.clear; |
| | 20 | | public StackOrientation stackOrientation = StackOrientation.VERTICAL; |
| 45 | 21 | | public bool adaptWidth = true; |
| 45 | 22 | | public bool adaptHeight = true; |
| | 23 | | public float spacing = 0; |
| | 24 | |
|
| | 25 | | public override BaseModel GetDataFromJSON(string json) => |
| 15 | 26 | | Utils.SafeFromJson<Model>(json); |
| | 27 | |
|
| | 28 | | public override BaseModel GetDataFromPb(ComponentBodyPayload pbModel) |
| | 29 | | { |
| 0 | 30 | | if (pbModel.PayloadCase != ComponentBodyPayload.PayloadOneofCase.UiContainerStack) |
| 0 | 31 | | return Utils.SafeUnimplemented<UIContainerStack, Model>(expected: ComponentBodyPayload.PayloadOneofC |
| | 32 | |
|
| 0 | 33 | | var pb = new Model(); |
| 0 | 34 | | if (pbModel.UiContainerStack.HasName) pb.name = pbModel.UiContainerStack.Name; |
| 0 | 35 | | if (pbModel.UiContainerStack.HasParentComponent) pb.parentComponent = pbModel.UiContainerStack.ParentCom |
| 0 | 36 | | if (pbModel.UiContainerStack.HasVisible) pb.visible = pbModel.UiContainerStack.Visible; |
| 0 | 37 | | if (pbModel.UiContainerStack.HasOpacity) pb.opacity = pbModel.UiContainerStack.Opacity; |
| 0 | 38 | | if (pbModel.UiContainerStack.HasHAlign) pb.hAlign = pbModel.UiContainerStack.HAlign; |
| 0 | 39 | | if (pbModel.UiContainerStack.HasVAlign) pb.vAlign = pbModel.UiContainerStack.VAlign; |
| 0 | 40 | | if (pbModel.UiContainerStack.Width != null) pb.width = SDK6DataMapExtensions.FromProtobuf(pb.width, pbMo |
| 0 | 41 | | if (pbModel.UiContainerStack.Height != null) pb.height = SDK6DataMapExtensions.FromProtobuf(pb.height, p |
| 0 | 42 | | if (pbModel.UiContainerStack.PositionX != null) pb.positionX = SDK6DataMapExtensions.FromProtobuf(pb.pos |
| 0 | 43 | | if (pbModel.UiContainerStack.PositionY != null) pb.positionY = SDK6DataMapExtensions.FromProtobuf(pb.pos |
| 0 | 44 | | if (pbModel.UiContainerStack.HasIsPointerBlocker) pb.isPointerBlocker = pbModel.UiContainerStack.IsPoint |
| | 45 | |
|
| 0 | 46 | | if (pbModel.UiContainerStack.HasStackOrientation) pb.stackOrientation = (StackOrientation)pbModel.UiCont |
| 0 | 47 | | if (pbModel.UiContainerStack.HasAdaptWidth) pb.adaptWidth = pbModel.UiContainerStack.AdaptWidth; |
| 0 | 48 | | if (pbModel.UiContainerStack.HasAdaptHeight) pb.adaptHeight = pbModel.UiContainerStack.AdaptHeight; |
| 0 | 49 | | if (pbModel.UiContainerStack.HasSpacing) pb.spacing = pbModel.UiContainerStack.Spacing; |
| 0 | 50 | | if (pbModel.UiContainerStack.Color != null) pb.color = pbModel.UiContainerStack.Color.AsUnityColor(); |
| | 51 | |
|
| 0 | 52 | | return pb; |
| | 53 | | } |
| | 54 | | } |
| | 55 | |
|
| | 56 | | public enum StackOrientation |
| | 57 | | { |
| | 58 | | VERTICAL, |
| | 59 | | HORIZONTAL |
| | 60 | | } |
| | 61 | |
|
| 11 | 62 | | public override string referencesContainerPrefabName => "UIContainerRect"; |
| | 63 | |
|
| 11 | 64 | | public Dictionary<string, GameObject> stackContainers = new Dictionary<string, GameObject>(); |
| | 65 | |
|
| | 66 | | HorizontalOrVerticalLayoutGroup layoutGroup; |
| | 67 | |
|
| 33 | 68 | | public UIContainerStack() { model = new Model(); } |
| | 69 | |
|
| 0 | 70 | | public override int GetClassId() { return (int) CLASS_ID.UI_CONTAINER_STACK; } |
| | 71 | |
|
| | 72 | | public override void AttachTo(IDCLEntity entity, System.Type overridenAttachedType = null) |
| | 73 | | { |
| 0 | 74 | | Debug.LogError( |
| | 75 | | "Aborted UIContainerStack attachment to an entity. UIShapes shouldn't be attached to entities."); |
| 0 | 76 | | } |
| | 77 | |
|
| 0 | 78 | | public override void DetachFrom(IDCLEntity entity, System.Type overridenAttachedType = null) { } |
| | 79 | |
|
| | 80 | | public override IEnumerator ApplyChanges(BaseModel newModel) |
| | 81 | | { |
| 18 | 82 | | referencesContainer.image.color = new Color(model.color.r, model.color.g, model.color.b, model.color.a); |
| 18 | 83 | | referencesContainer.image.raycastTarget = model.color.a >= RAYCAST_ALPHA_THRESHOLD; |
| | 84 | |
|
| 18 | 85 | | if (model.stackOrientation == StackOrientation.VERTICAL && !(layoutGroup is VerticalLayoutGroup)) |
| | 86 | | { |
| 11 | 87 | | Object.DestroyImmediate(layoutGroup, false); |
| 11 | 88 | | layoutGroup = childHookRectTransform.gameObject.AddComponent<VerticalLayoutGroup>(); |
| | 89 | | } |
| 7 | 90 | | else if (model.stackOrientation == StackOrientation.HORIZONTAL && !(layoutGroup is HorizontalLayoutGroup)) |
| | 91 | | { |
| 2 | 92 | | Object.DestroyImmediate(layoutGroup, false); |
| 2 | 93 | | layoutGroup = childHookRectTransform.gameObject.AddComponent<HorizontalLayoutGroup>(); |
| | 94 | | } |
| | 95 | |
|
| 18 | 96 | | layoutGroup.childControlHeight = false; |
| 18 | 97 | | layoutGroup.childControlWidth = false; |
| 18 | 98 | | layoutGroup.childForceExpandWidth = false; |
| 18 | 99 | | layoutGroup.childForceExpandHeight = false; |
| 18 | 100 | | layoutGroup.spacing = model.spacing; |
| | 101 | |
|
| 18 | 102 | | referencesContainer.sizeFitter.adjustHeight = model.adaptHeight; |
| 18 | 103 | | referencesContainer.sizeFitter.adjustWidth = model.adaptWidth; |
| | 104 | |
|
| 18 | 105 | | MarkLayoutDirty(); |
| 18 | 106 | | return null; |
| | 107 | | } |
| | 108 | |
|
| | 109 | | void RefreshContainerForShape(BaseDisposable updatedComponent) |
| | 110 | | { |
| 43 | 111 | | UIShape childComponent = updatedComponent as UIShape; |
| 43 | 112 | | Assert.IsTrue(childComponent != null, "This should never happen!!!!"); |
| | 113 | |
|
| 43 | 114 | | if (((UIShape.Model)childComponent.GetModel()).parentComponent != this.id) |
| | 115 | | { |
| 26 | 116 | | MarkLayoutDirty(); |
| 26 | 117 | | return; |
| | 118 | | } |
| | 119 | |
|
| 17 | 120 | | GameObject stackContainer = null; |
| | 121 | |
|
| 17 | 122 | | if (!stackContainers.ContainsKey(childComponent.id)) |
| | 123 | | { |
| 17 | 124 | | stackContainer = Object.Instantiate(Resources.Load("UIContainerStackChild")) as GameObject; |
| | 125 | | #if UNITY_EDITOR |
| 17 | 126 | | stackContainer.name = "UIContainerStackChild - " + childComponent.id; |
| | 127 | | #endif |
| 17 | 128 | | stackContainers.Add(childComponent.id, stackContainer); |
| | 129 | |
|
| 17 | 130 | | int oldSiblingIndex = childComponent.referencesContainer.transform.GetSiblingIndex(); |
| 17 | 131 | | childComponent.referencesContainer.transform.SetParent(stackContainer.transform, false); |
| 17 | 132 | | stackContainer.transform.SetParent(referencesContainer.childHookRectTransform, false); |
| 17 | 133 | | stackContainer.transform.SetSiblingIndex(oldSiblingIndex); |
| | 134 | | } |
| | 135 | | else |
| | 136 | | { |
| 0 | 137 | | stackContainer = stackContainers[childComponent.id]; |
| | 138 | | } |
| | 139 | |
|
| 17 | 140 | | MarkLayoutDirty(); |
| 17 | 141 | | } |
| | 142 | |
|
| | 143 | | public override void OnChildAttached(UIShape parentComponent, UIShape childComponent) |
| | 144 | | { |
| 36 | 145 | | RefreshContainerForShape(childComponent); |
| 36 | 146 | | childComponent.OnAppliedChanges -= RefreshContainerForShape; |
| 36 | 147 | | childComponent.OnAppliedChanges += RefreshContainerForShape; |
| 36 | 148 | | } |
| | 149 | |
|
| | 150 | | public override void RefreshDCLLayoutRecursively(bool refreshSize = true, |
| | 151 | | bool refreshAlignmentAndPosition = true) |
| | 152 | | { |
| 34 | 153 | | base.RefreshDCLLayoutRecursively(refreshSize, refreshAlignmentAndPosition); |
| 34 | 154 | | referencesContainer.sizeFitter.RefreshRecursively(); |
| 34 | 155 | | } |
| | 156 | |
|
| | 157 | | public override void OnChildDetached(UIShape parentComponent, UIShape childComponent) |
| | 158 | | { |
| 5 | 159 | | if (parentComponent != this) |
| | 160 | | { |
| 5 | 161 | | return; |
| | 162 | | } |
| | 163 | |
|
| 0 | 164 | | if (stackContainers.ContainsKey(childComponent.id)) |
| | 165 | | { |
| 0 | 166 | | Object.Destroy(stackContainers[childComponent.id]); |
| 0 | 167 | | stackContainers[childComponent.id].transform.SetParent(null); |
| 0 | 168 | | stackContainers[childComponent.id].name += "- Detached"; |
| 0 | 169 | | stackContainers.Remove(childComponent.id); |
| | 170 | | } |
| | 171 | |
|
| 0 | 172 | | childComponent.OnAppliedChanges -= RefreshContainerForShape; |
| 0 | 173 | | RefreshDCLLayout(); |
| 0 | 174 | | } |
| | 175 | |
|
| | 176 | | public override void Dispose() |
| | 177 | | { |
| 1 | 178 | | if (referencesContainer != null) |
| 1 | 179 | | Utils.SafeDestroy(referencesContainer.gameObject); |
| | 180 | |
|
| 1 | 181 | | base.Dispose(); |
| 1 | 182 | | } |
| | 183 | | } |
| | 184 | | } |