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 }