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); 92 case CENTER_HORIZONTAL: 93 return "Center horizontally"; 94 case LEFT: 95 if (!createCell) { 96 return String.format("Insert into column %1$d", cellIndex); 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); 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); 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); 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); 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); 124 } 125 return String.format("Align bottom at y=%1d", matchedLine - layout.getBounds().y); 126 case CENTER_VERTICAL: 127 case UNKNOWN: 128 default: 129 return null; 130 } 131 } 132 133 /** 134 * Computes the sorting priority of this match, giving baseline matches higher 135 * precedence than centering which in turn is ordered before external edge matches 136 */ 137 private int getPriority() { 138 switch (type) { 139 case BASELINE: 140 return 0; 141 case CENTER_HORIZONTAL: 142 case CENTER_VERTICAL: 143 return 1; 144 case BOTTOM: 145 case LEFT: 146 case RIGHT: 147 case TOP: 148 return 2; 149 } 150 151 return 3; 152 } 153 }