1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.constraintlayout.core.widgets;
18 
19 import androidx.constraintlayout.core.Cache;
20 
21 import java.util.ArrayList;
22 
23 /**
24  * A container of ConstraintWidget
25  */
26 public class WidgetContainer extends ConstraintWidget {
27     public ArrayList<ConstraintWidget> mChildren = new ArrayList<>();
28 
29     /*-----------------------------------------------------------------------*/
30     // Construction
31     /*-----------------------------------------------------------------------*/
32 
33     /**
34      * Default constructor
35      */
WidgetContainer()36     public WidgetContainer() {
37     }
38 
39     /**
40      * Constructor
41      *
42      * @param x      x position
43      * @param y      y position
44      * @param width  width of the layout
45      * @param height height of the layout
46      */
WidgetContainer(int x, int y, int width, int height)47     public WidgetContainer(int x, int y, int width, int height) {
48         super(x, y, width, height);
49     }
50 
51     /**
52      * Constructor
53      *
54      * @param width  width of the layout
55      * @param height height of the layout
56      */
WidgetContainer(int width, int height)57     public WidgetContainer(int width, int height) {
58         super(width, height);
59     }
60 
61     @Override
reset()62     public void reset() {
63         mChildren.clear();
64         super.reset();
65     }
66 
67     /**
68      * Add a child widget
69      *
70      * @param widget to add
71      */
add(ConstraintWidget widget)72     public void add(ConstraintWidget widget) {
73         mChildren.add(widget);
74         if (widget.getParent() != null) {
75             WidgetContainer container = (WidgetContainer) widget.getParent();
76             container.remove(widget);
77         }
78         widget.setParent(this);
79     }
80 
81     /**
82      * Add multiple child widgets.
83      *
84      * @param widgets to add
85      */
add(ConstraintWidget... widgets)86     public void add(ConstraintWidget... widgets) {
87         final int count = widgets.length;
88         for (int i = 0; i < count; i++) {
89             add(widgets[i]);
90         }
91     }
92 
93     /**
94      * Remove a child widget
95      *
96      * @param widget to remove
97      */
remove(ConstraintWidget widget)98     public void remove(ConstraintWidget widget) {
99         mChildren.remove(widget);
100         widget.reset();
101     }
102 
103     /**
104      * Access the children
105      *
106      * @return the array of children
107      */
getChildren()108     public ArrayList<ConstraintWidget> getChildren() {
109         return mChildren;
110     }
111 
112     /**
113      * Return the top-level ConstraintWidgetContainer
114      *
115      * @return top-level ConstraintWidgetContainer
116      */
getRootConstraintContainer()117     public ConstraintWidgetContainer getRootConstraintContainer() {
118         ConstraintWidget item = this;
119         ConstraintWidget parent = item.getParent();
120         ConstraintWidgetContainer container = null;
121         if (item instanceof ConstraintWidgetContainer) {
122             container = (ConstraintWidgetContainer) this;
123         }
124         while (parent != null) {
125             item = parent;
126             parent = item.getParent();
127             if (item instanceof ConstraintWidgetContainer) {
128                 container = (ConstraintWidgetContainer) item;
129             }
130         }
131         return container;
132     }
133 
134     /*-----------------------------------------------------------------------*/
135     // Overloaded methods from ConstraintWidget
136     /*-----------------------------------------------------------------------*/
137 
138     /**
139      * Set the offset of this widget relative to the root widget.
140      * We then set the offset of our children as well.
141      *
142      * @param x horizontal offset
143      * @param y vertical offset
144      */
145     @Override
setOffset(int x, int y)146     public void setOffset(int x, int y) {
147         super.setOffset(x, y);
148         final int count = mChildren.size();
149         for (int i = 0; i < count; i++) {
150             ConstraintWidget widget = mChildren.get(i);
151             widget.setOffset(getRootX(), getRootY());
152         }
153     }
154 
155     /**
156      * Function implemented by ConstraintWidgetContainer
157      */
layout()158     public void layout() {
159         if (mChildren == null) {
160             return;
161         }
162         final int count = mChildren.size();
163         for (int i = 0; i < count; i++) {
164             ConstraintWidget widget = mChildren.get(i);
165             if (widget instanceof WidgetContainer) {
166                 ((WidgetContainer) widget).layout();
167             }
168         }
169     }
170 
171     @Override
resetSolverVariables(Cache cache)172     public void resetSolverVariables(Cache cache) {
173         super.resetSolverVariables(cache);
174         final int count = mChildren.size();
175         for (int i = 0; i < count; i++) {
176             ConstraintWidget widget = mChildren.get(i);
177             widget.resetSolverVariables(cache);
178         }
179     }
180 
181     // @TODO: add description
removeAllChildren()182     public void removeAllChildren() {
183         mChildren.clear();
184     }
185 }
186