1 package com.android.launcher3.util;
2 
3 import android.graphics.Rect;
4 
5 import com.android.launcher3.ItemInfo;
6 
7 /**
8  * Utility object to manage the occupancy in a grid.
9  */
10 public class GridOccupancy {
11 
12     private final int mCountX;
13     private final int mCountY;
14 
15     public final boolean[][] cells;
16 
GridOccupancy(int countX, int countY)17     public GridOccupancy(int countX, int countY) {
18         mCountX = countX;
19         mCountY = countY;
20         cells = new boolean[countX][countY];
21     }
22 
23     /**
24      * Find the first vacant cell, if there is one.
25      *
26      * @param vacantOut Holds the x and y coordinate of the vacant cell
27      * @param spanX Horizontal cell span.
28      * @param spanY Vertical cell span.
29      *
30      * @return true if a vacant cell was found
31      */
findVacantCell(int[] vacantOut, int spanX, int spanY)32     public boolean findVacantCell(int[] vacantOut, int spanX, int spanY) {
33         for (int y = 0; (y + spanY) <= mCountY; y++) {
34             for (int x = 0; (x + spanX) <= mCountX; x++) {
35                 boolean available = !cells[x][y];
36                 out:
37                 for (int i = x; i < x + spanX; i++) {
38                     for (int j = y; j < y + spanY; j++) {
39                         available = available && !cells[i][j];
40                         if (!available) break out;
41                     }
42                 }
43                 if (available) {
44                     vacantOut[0] = x;
45                     vacantOut[1] = y;
46                     return true;
47                 }
48             }
49         }
50         return false;
51     }
52 
copyTo(GridOccupancy dest)53     public void copyTo(GridOccupancy dest) {
54         for (int i = 0; i < mCountX; i++) {
55             for (int j = 0; j < mCountY; j++) {
56                 dest.cells[i][j] = cells[i][j];
57             }
58         }
59     }
60 
isRegionVacant(int x, int y, int spanX, int spanY)61     public boolean isRegionVacant(int x, int y, int spanX, int spanY) {
62         int x2 = x + spanX - 1;
63         int y2 = y + spanY - 1;
64         if (x < 0 || y < 0 || x2 >= mCountX || y2 >= mCountY) {
65             return false;
66         }
67         for (int i = x; i <= x2; i++) {
68             for (int j = y; j <= y2; j++) {
69                 if (cells[i][j]) {
70                     return false;
71                 }
72             }
73         }
74         return true;
75     }
76 
markCells(int cellX, int cellY, int spanX, int spanY, boolean value)77     public void markCells(int cellX, int cellY, int spanX, int spanY, boolean value) {
78         if (cellX < 0 || cellY < 0) return;
79         for (int x = cellX; x < cellX + spanX && x < mCountX; x++) {
80             for (int y = cellY; y < cellY + spanY && y < mCountY; y++) {
81                 cells[x][y] = value;
82             }
83         }
84     }
85 
markCells(Rect r, boolean value)86     public void markCells(Rect r, boolean value) {
87         markCells(r.left, r.top, r.width(), r.height(), value);
88     }
89 
markCells(CellAndSpan cell, boolean value)90     public void markCells(CellAndSpan cell, boolean value) {
91         markCells(cell.cellX, cell.cellY, cell.spanX, cell.spanY, value);
92     }
93 
markCells(ItemInfo item, boolean value)94     public void markCells(ItemInfo item, boolean value) {
95         markCells(item.cellX, item.cellY, item.spanX, item.spanY, value);
96     }
97 
clear()98     public void clear() {
99         markCells(0, 0, mCountX, mCountY, false);
100     }
101 }
102