Home | History | Annotate | Download | only in grid
      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.grid;
     17 
     18 import static com.android.ide.common.layout.grid.GridModel.UNDEFINED;
     19 
     20 import com.android.ide.common.api.INode;
     21 import com.android.ide.common.api.SegmentType;
     22 
     23 /**
     24  * A match for a drag within a GridLayout, corresponding to an alignment with another
     25  * edge, or a margin, or centering, or a gap distance from another edge and so on.
     26  */
     27 class GridMatch implements Comparable<GridMatch> {
     28     /** The distance to the matched edge - used to pick best matches */
     29     public final int distance;
     30 
     31     /** Type of edge that was matched (this refers to the edge on the dragged node,
     32      * not on the matched node/row/cell etc) */
     33     public final SegmentType type;
     34 
     35     /** Row or column for the match */
     36     public int cellIndex;
     37 
     38     /** If true, create a new row/column */
     39     public boolean createCell;
     40 
     41     /** The actual x or y position of the matched segment */
     42     public int matchedLine;
     43 
     44     /** Amount of margin between the matched edges */
     45     public int margin;
     46 
     47     /**
     48      * Constructs a match.
     49      *
     50      * @param type the edge of the dragged element that was matched
     51      * @param distance the absolute distance from the ideal match - used to find the best
     52      *            match
     53      * @param matchedLine the actual X or Y location of the ideal match
     54      * @param cellIndex the index of the row or column we matched with
     55      * @param createCell if true, create a new cell by splitting the existing cell at the
     56      *            matchedLine position
     57      * @param margin a margin distance to add to the actual location from the matched line
     58      */
     59     GridMatch(SegmentType type, int distance, int matchedLine, int cellIndex,
     60             boolean createCell, int margin) {
     61         super();
     62         this.type = type;
     63         this.distance = distance;
     64         this.matchedLine = matchedLine;
     65         this.cellIndex = cellIndex;
     66         this.createCell = createCell;
     67         this.margin = margin;
     68     }
     69 
     70     // Implements Comparable<GridMatch>
     71     @Override
     72     public int compareTo(GridMatch o) {
     73         // Pick closest matches first
     74         if (distance != o.distance) {
     75             return distance - o.distance;
     76         }
     77 
     78         // Prefer some types of matches over other matches
     79         return getPriority() - o.getPriority();
     80     }
     81 
     82     /**
     83      * Describes the match for the user
     84      *
     85      * @param layout the GridLayout containing the match
     86      * @return a short description for the user of the match
     87      */
     88     public String getDisplayName(INode layout) {
     89         switch (type) {
     90             case BASELINE:
     91                 return String.format("Align baseline in row %1$d", cellIndex + 1);
     92             case CENTER_HORIZONTAL:
     93                 return "Center horizontally";
     94             case LEFT:
     95                 if (!createCell) {
     96                     return String.format("Insert into column %1$d", cellIndex + 1);
     97                 }
     98                 if (margin != UNDEFINED) {
     99                     if (cellIndex == 0 && margin != 0) {
    100                         return "Add one margin distance from the left";
    101                     }
    102                     return String.format("Add next to column %1$d", cellIndex + 1);
    103                 }
    104                 return String.format("Align left at x=%1$d", matchedLine - layout.getBounds().x);
    105             case RIGHT:
    106                 if (!createCell) {
    107                     return String.format("Insert right-aligned into column %1$d", cellIndex + 1);
    108                 }
    109                 return String.format("Align right at x=%1$d", matchedLine - layout.getBounds().x);
    110             case TOP:
    111                 if (!createCell) {
    112                     return String.format("Insert into row %1$d", cellIndex + 1);
    113                 }
    114                 if (margin != UNDEFINED) {
    115                     if (cellIndex == 0 && margin != 0) {
    116                         return "Add one margin distance from the top";
    117                     }
    118                     return String.format("Add below row %1$d", cellIndex + 1);
    119                 }
    120                 return String.format("Align top at y=%1d", matchedLine - layout.getBounds().y);
    121             case BOTTOM:
    122                 if (!createCell) {
    123                     return String.format("Insert into bottom of row %1$d", cellIndex + 1);
    124                 }
    125                 return String.format("Align bottom at y=%1d", matchedLine - layout.getBounds().y);
    126             case CENTER_VERTICAL:
    127                 return "Center vertically";
    128             case UNKNOWN:
    129             default:
    130                 return null;
    131         }
    132     }
    133 
    134     /**
    135      * Computes the sorting priority of this match, giving baseline matches higher
    136      * precedence than centering which in turn is ordered before external edge matches
    137      */
    138     private int getPriority() {
    139         switch (type) {
    140             case BASELINE:
    141                 return 0;
    142             case CENTER_HORIZONTAL:
    143             case CENTER_VERTICAL:
    144                 return 1;
    145             case BOTTOM:
    146             case LEFT:
    147             case RIGHT:
    148             case TOP:
    149                 return 2;
    150         }
    151 
    152         return 3;
    153     }
    154 }