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 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 */ 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 */ 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 */ 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 }