Home | History | Annotate | Download | only in relative
      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 }