1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 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.launcher3.celllayout; 17 18 import android.content.Context; 19 import android.graphics.Point; 20 import android.graphics.Rect; 21 import android.util.AttributeSet; 22 import android.view.ViewDebug; 23 import android.view.ViewGroup; 24 25 import androidx.annotation.Nullable; 26 27 /** 28 * Represents the logic of where a view is in a CellLayout and its size 29 */ 30 public class CellLayoutLayoutParams extends ViewGroup.MarginLayoutParams { 31 32 @ViewDebug.ExportedProperty 33 private int mCellX; 34 35 @ViewDebug.ExportedProperty 36 private int mCellY; 37 38 private int mTmpCellX; 39 40 private int mTmpCellY; 41 42 /** 43 * Indicates that the temporary coordinates should be used to layout the items 44 */ 45 public boolean useTmpCoords; 46 47 /** 48 * Number of cells spanned horizontally by the item. 49 */ 50 @ViewDebug.ExportedProperty 51 public int cellHSpan; 52 53 /** 54 * Number of cells spanned vertically by the item. 55 */ 56 @ViewDebug.ExportedProperty 57 public int cellVSpan; 58 59 /** 60 * Indicates whether the item will set its x, y, width and height parameters freely, 61 * or whether these will be computed based on cellX, cellY, cellHSpan and cellVSpan. 62 */ 63 public boolean isLockedToGrid = true; 64 65 /** 66 * Indicates whether this item can be reordered. Always true except in the case of the 67 * the AllApps button and QSB place holder. 68 */ 69 public boolean canReorder = true; 70 71 // X coordinate of the view in the layout. 72 @ViewDebug.ExportedProperty 73 public int x; 74 // Y coordinate of the view in the layout. 75 @ViewDebug.ExportedProperty 76 public int y; 77 78 public boolean dropped; 79 CellLayoutLayoutParams(Context c, AttributeSet attrs)80 public CellLayoutLayoutParams(Context c, AttributeSet attrs) { 81 super(c, attrs); 82 cellHSpan = 1; 83 cellVSpan = 1; 84 } 85 CellLayoutLayoutParams(ViewGroup.LayoutParams source)86 public CellLayoutLayoutParams(ViewGroup.LayoutParams source) { 87 super(source); 88 cellHSpan = 1; 89 cellVSpan = 1; 90 } 91 CellLayoutLayoutParams(CellLayoutLayoutParams source)92 public CellLayoutLayoutParams(CellLayoutLayoutParams source) { 93 super(source); 94 this.mCellX = source.getCellX(); 95 this.mCellY = source.getCellY(); 96 this.cellHSpan = source.cellHSpan; 97 this.cellVSpan = source.cellVSpan; 98 this.mTmpCellX = source.getTmpCellX(); 99 this.mTmpCellY = source.getTmpCellY(); 100 this.useTmpCoords = source.useTmpCoords; 101 } 102 CellLayoutLayoutParams(int cellX, int cellY, int cellHSpan, int cellVSpan)103 public CellLayoutLayoutParams(int cellX, int cellY, int cellHSpan, int cellVSpan) { 104 super(CellLayoutLayoutParams.MATCH_PARENT, CellLayoutLayoutParams.MATCH_PARENT); 105 this.mCellX = cellX; 106 this.mCellY = cellY; 107 this.cellHSpan = cellHSpan; 108 this.cellVSpan = cellVSpan; 109 } 110 111 /** 112 * Updates the {@link CellLayoutLayoutParams} with the right measures using their 113 * full/invariant device profile sizes. 114 */ setup(int cellWidth, int cellHeight, boolean invertHorizontally, int colCount, int rowCount, Point borderSpace)115 public void setup(int cellWidth, int cellHeight, boolean invertHorizontally, int colCount, 116 int rowCount, Point borderSpace) { 117 setup(cellWidth, cellHeight, invertHorizontally, colCount, rowCount, 1.0f, 1.0f, 118 borderSpace, null); 119 } 120 121 /** 122 * Use this method, as opposed to {@link #setup(int, int, boolean, int, int, Point)}, 123 * if the view needs to be scaled. 124 * 125 * ie. In multi-window mode, we setup widgets so that they are measured and laid out 126 * using their full/invariant device profile sizes. 127 */ setup(int cellWidth, int cellHeight, boolean invertHorizontally, int colCount, int rowCount, float cellScaleX, float cellScaleY, Point borderSpace, @Nullable Rect inset)128 public void setup(int cellWidth, int cellHeight, boolean invertHorizontally, int colCount, 129 int rowCount, float cellScaleX, float cellScaleY, Point borderSpace, 130 @Nullable Rect inset) { 131 if (isLockedToGrid) { 132 final int myCellHSpan = cellHSpan; 133 final int myCellVSpan = cellVSpan; 134 int myCellX = useTmpCoords ? getTmpCellX() : getCellX(); 135 int myCellY = useTmpCoords ? getTmpCellY() : getCellY(); 136 137 if (invertHorizontally) { 138 myCellX = colCount - myCellX - cellHSpan; 139 } 140 141 int hBorderSpacing = (myCellHSpan - 1) * borderSpace.x; 142 int vBorderSpacing = (myCellVSpan - 1) * borderSpace.y; 143 144 float myCellWidth = ((myCellHSpan * cellWidth) + hBorderSpacing) / cellScaleX; 145 float myCellHeight = ((myCellVSpan * cellHeight) + vBorderSpacing) / cellScaleY; 146 147 width = Math.round(myCellWidth) - leftMargin - rightMargin; 148 height = Math.round(myCellHeight) - topMargin - bottomMargin; 149 x = leftMargin + (myCellX * cellWidth) + (myCellX * borderSpace.x); 150 y = topMargin + (myCellY * cellHeight) + (myCellY * borderSpace.y); 151 152 if (inset != null) { 153 x += inset.left; 154 y += inset.top; 155 width -= inset.left + inset.right; 156 height -= inset.top + inset.bottom; 157 } 158 } 159 } 160 161 /** 162 * Sets the position to the provided point 163 */ setCellXY(Point point)164 public void setCellXY(Point point) { 165 setCellX(point.x); 166 setCellY(point.y); 167 } 168 169 /** 170 * @return the string representation of the position of the {@link CellLayoutLayoutParams} 171 */ toString()172 public String toString() { 173 return "(" + this.getCellX() + ", " + this.getCellY() + ")"; 174 } 175 176 /** 177 * Horizontal location of the item in the grid. 178 */ getCellX()179 public int getCellX() { 180 return mCellX; 181 } 182 setCellX(int cellX)183 public void setCellX(int cellX) { 184 this.mCellX = cellX; 185 } 186 187 /** 188 * Vertical location of the item in the grid. 189 */ getCellY()190 public int getCellY() { 191 return mCellY; 192 } 193 setCellY(int cellY)194 public void setCellY(int cellY) { 195 this.mCellY = cellY; 196 } 197 198 /** 199 * Temporary horizontal location of the item in the grid during reorder 200 */ getTmpCellX()201 public int getTmpCellX() { 202 return mTmpCellX; 203 } 204 setTmpCellX(int tmpCellX)205 public void setTmpCellX(int tmpCellX) { 206 this.mTmpCellX = tmpCellX; 207 } 208 209 /** 210 * Temporary vertical location of the item in the grid during reorder 211 */ getTmpCellY()212 public int getTmpCellY() { 213 return mTmpCellY; 214 } 215 setTmpCellY(int tmpCellY)216 public void setTmpCellY(int tmpCellY) { 217 this.mTmpCellY = tmpCellY; 218 } 219 } 220