• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
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 package com.android.ide.common.layout.relative;
17 
18 import static com.android.ide.common.api.SegmentType.BASELINE;
19 import static com.android.ide.common.api.SegmentType.BOTTOM;
20 import static com.android.ide.common.api.SegmentType.CENTER_HORIZONTAL;
21 import static com.android.ide.common.api.SegmentType.CENTER_VERTICAL;
22 import static com.android.ide.common.api.SegmentType.LEFT;
23 import static com.android.ide.common.api.SegmentType.RIGHT;
24 import static com.android.ide.common.api.SegmentType.TOP;
25 import static com.android.ide.common.api.SegmentType.UNKNOWN;
26 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ABOVE;
27 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ALIGN_BASELINE;
28 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ALIGN_BOTTOM;
29 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ALIGN_LEFT;
30 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ALIGN_PARENT_BOTTOM;
31 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ALIGN_PARENT_LEFT;
32 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ALIGN_PARENT_RIGHT;
33 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ALIGN_PARENT_TOP;
34 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ALIGN_RIGHT;
35 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_ALIGN_TOP;
36 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_BELOW;
37 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_CENTER_HORIZONTAL;
38 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_CENTER_IN_PARENT;
39 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_CENTER_VERTICAL;
40 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_TO_LEFT_OF;
41 import static com.android.ide.common.layout.LayoutConstants.ATTR_LAYOUT_TO_RIGHT_OF;
42 
43 import com.android.ide.common.api.SegmentType;
44 
45 import java.util.HashMap;
46 import java.util.Map;
47 
48 /**
49  * Each constraint type corresponds to a type of constraint available for the
50  * RelativeLayout; for example, {@link #LAYOUT_ABOVE} corresponds to the layout_above constraint.
51  */
52 enum ConstraintType {
53     LAYOUT_ABOVE(ATTR_LAYOUT_ABOVE,
54             null /* sourceX */, BOTTOM, null /* targetX */, TOP,
55             false /* targetParent */, true /* horizontalEdge */, false /* verticalEdge */,
56             true /* relativeToMargin */),
57 
58     LAYOUT_BELOW(ATTR_LAYOUT_BELOW, null, TOP, null, BOTTOM, false, true, false, true),
59     ALIGN_TOP(ATTR_LAYOUT_ALIGN_TOP, null, TOP, null, TOP, false, true, false, false),
60     ALIGN_BOTTOM(ATTR_LAYOUT_ALIGN_BOTTOM, null, BOTTOM, null, BOTTOM, false, true, false, false),
61     ALIGN_LEFT(ATTR_LAYOUT_ALIGN_LEFT, LEFT, null, LEFT, null, false, false, true, false),
62     ALIGN_RIGHT(ATTR_LAYOUT_ALIGN_RIGHT, RIGHT, null, RIGHT, null, false, false, true, false),
63     LAYOUT_LEFT_OF(ATTR_LAYOUT_TO_LEFT_OF, RIGHT, null, LEFT, null, false, false, true, true),
64     LAYOUT_RIGHT_OF(ATTR_LAYOUT_TO_RIGHT_OF, LEFT, null, RIGHT, null, false, false, true, true),
65     ALIGN_PARENT_TOP(ATTR_LAYOUT_ALIGN_PARENT_TOP, null, TOP, null, TOP, true, true, false, false),
66     ALIGN_BASELINE(ATTR_LAYOUT_ALIGN_BASELINE, null, BASELINE, null, BASELINE, false, true, false,
67             false),
68     ALIGN_PARENT_LEFT(ATTR_LAYOUT_ALIGN_PARENT_LEFT, LEFT, null, LEFT, null, true, false, true,
69             false),
70     ALIGN_PARENT_RIGHT(ATTR_LAYOUT_ALIGN_PARENT_RIGHT, RIGHT, null, RIGHT, null, true, false, true,
71             false),
72     ALIGN_PARENT_BOTTOM(ATTR_LAYOUT_ALIGN_PARENT_BOTTOM, null, BOTTOM, null, BOTTOM, true, true,
73             false, false),
74     LAYOUT_CENTER_HORIZONTAL(ATTR_LAYOUT_CENTER_HORIZONTAL, CENTER_VERTICAL, null, CENTER_VERTICAL,
75             null, true, true, false, false),
76     LAYOUT_CENTER_VERTICAL(ATTR_LAYOUT_CENTER_VERTICAL, null, CENTER_HORIZONTAL, null,
77             CENTER_HORIZONTAL, true, false, true, false),
78     LAYOUT_CENTER_IN_PARENT(ATTR_LAYOUT_CENTER_IN_PARENT, CENTER_VERTICAL, CENTER_HORIZONTAL,
79             CENTER_VERTICAL, CENTER_HORIZONTAL, true, true, true, false);
80 
ConstraintType(String name, SegmentType sourceSegmentTypeX, SegmentType sourceSegmentTypeY, SegmentType targetSegmentTypeX, SegmentType targetSegmentTypeY, boolean targetParent, boolean horizontalEdge, boolean verticalEdge, boolean relativeToMargin)81     private ConstraintType(String name, SegmentType sourceSegmentTypeX,
82             SegmentType sourceSegmentTypeY, SegmentType targetSegmentTypeX,
83             SegmentType targetSegmentTypeY, boolean targetParent, boolean horizontalEdge,
84             boolean verticalEdge, boolean relativeToMargin) {
85         assert horizontalEdge || verticalEdge;
86 
87         this.name = name;
88         this.sourceSegmentTypeX = sourceSegmentTypeX != null ? sourceSegmentTypeX : UNKNOWN;
89         this.sourceSegmentTypeY = sourceSegmentTypeY != null ? sourceSegmentTypeY : UNKNOWN;
90         this.targetSegmentTypeX = targetSegmentTypeX != null ? targetSegmentTypeX : UNKNOWN;
91         this.targetSegmentTypeY = targetSegmentTypeY != null ? targetSegmentTypeY : UNKNOWN;
92         this.targetParent = targetParent;
93         this.horizontalEdge = horizontalEdge;
94         this.verticalEdge = verticalEdge;
95         this.relativeToMargin = relativeToMargin;
96     }
97 
98     /** The attribute name of the constraint */
99     public final String name;
100 
101     /** The horizontal position of the source of the constraint */
102     public final SegmentType sourceSegmentTypeX;
103 
104     /** The vertical position of the source of the constraint */
105     public final SegmentType sourceSegmentTypeY;
106 
107     /** The horizontal position of the target of the constraint */
108     public final SegmentType targetSegmentTypeX;
109 
110     /** The vertical position of the target of the constraint */
111     public final SegmentType targetSegmentTypeY;
112 
113     /**
114      * If true, the constraint targets the parent layout, otherwise it targets another
115      * view
116      */
117     public final boolean targetParent;
118 
119     /** If true, this constraint affects the horizontal dimension */
120     public final boolean horizontalEdge;
121 
122     /** If true, this constraint affects the vertical dimension */
123     public final boolean verticalEdge;
124 
125     /**
126      * Whether this constraint is relative to the margin bounds of the node rather than
127      * the node's actual bounds
128      */
129     public final boolean relativeToMargin;
130 
131     /** Map from attribute name to constraint type */
132     private static Map<String, ConstraintType> sNameToType;
133 
134     /**
135      * Returns the {@link ConstraintType} corresponding to the given attribute name, or
136      * null if not found.
137      *
138      * @param attribute the name of the attribute to look up
139      * @return the corresponding {@link ConstraintType}
140      */
fromAttribute(String attribute)141     public static ConstraintType fromAttribute(String attribute) {
142         if (sNameToType == null) {
143             ConstraintType[] types = ConstraintType.values();
144             Map<String, ConstraintType> map = new HashMap<String, ConstraintType>(types.length);
145             for (ConstraintType type : types) {
146                 map.put(type.name, type);
147             }
148             sNameToType = map;
149         }
150         return sNameToType.get(attribute);
151     }
152 
153     /**
154      * Returns true if this constraint type represents a constraint where the target edge
155      * is one of the parent edges (actual edge, not center/baseline segments)
156      *
157      * @return true if the target segment is a parent edge
158      */
isRelativeToParentEdge()159     public boolean isRelativeToParentEdge() {
160         return this == ALIGN_PARENT_LEFT || this == ALIGN_PARENT_RIGHT || this == ALIGN_PARENT_TOP
161                 || this == ALIGN_PARENT_BOTTOM;
162     }
163 
164     /**
165      * Returns a {@link ConstraintType} for a potential match of edges.
166      *
167      * @param withParent if true, the target is the parent
168      * @param from the source edge
169      * @param to the target edge
170      * @return a {@link ConstraintType}, or null
171      */
forMatch(boolean withParent, SegmentType from, SegmentType to)172     public static ConstraintType forMatch(boolean withParent, SegmentType from, SegmentType to) {
173         // Attached to parent edge?
174         if (withParent) {
175             switch (from) {
176                 case TOP:
177                     return ALIGN_PARENT_TOP;
178                 case BOTTOM:
179                     return ALIGN_PARENT_BOTTOM;
180                 case LEFT:
181                     return ALIGN_PARENT_LEFT;
182                 case RIGHT:
183                     return ALIGN_PARENT_RIGHT;
184                 case CENTER_HORIZONTAL:
185                     return LAYOUT_CENTER_VERTICAL;
186                 case CENTER_VERTICAL:
187                     return LAYOUT_CENTER_HORIZONTAL;
188             }
189 
190             return null;
191         }
192 
193         // Attached to some other node.
194         switch (from) {
195             case TOP:
196                 switch (to) {
197                     case TOP:
198                         return ALIGN_TOP;
199                     case BOTTOM:
200                         return LAYOUT_BELOW;
201                     case BASELINE:
202                         return ALIGN_BASELINE;
203                 }
204                 break;
205             case BOTTOM:
206                 switch (to) {
207                     case TOP:
208                         return LAYOUT_ABOVE;
209                     case BOTTOM:
210                         return ALIGN_BOTTOM;
211                     case BASELINE:
212                         return ALIGN_BASELINE;
213                 }
214                 break;
215             case LEFT:
216                 switch (to) {
217                     case LEFT:
218                         return ALIGN_LEFT;
219                     case RIGHT:
220                         return LAYOUT_RIGHT_OF;
221                 }
222                 break;
223             case RIGHT:
224                 switch (to) {
225                     case LEFT:
226                         return LAYOUT_LEFT_OF;
227                     case RIGHT:
228                         return ALIGN_RIGHT;
229                 }
230                 break;
231             case BASELINE:
232                 return ALIGN_BASELINE;
233         }
234 
235         return null;
236     }
237 }