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 }