1 /* 2 * Copyright (C) 2023 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.testgenerator 17 18 import android.graphics.Rect 19 import com.android.launcher3.celllayout.board.CellLayoutBoard 20 import java.util.Random 21 22 /** Generates a random CellLayoutBoard. */ 23 open class RandomBoardGenerator(generator: Random) : DeterministicRandomGenerator(generator) { 24 25 companion object { 26 // This is the max number of widgets because we encode the widgets as letters A-Z and we 27 // already have some of those letter used by other things so 22 is a safe number 28 val MAX_NUMBER_OF_WIDGETS = 22 29 } 30 31 /** 32 * @param remainingEmptySpaces the maximum number of spaces we will fill with icons and widgets 33 * meaning that if the number is 100 we will try to fill the board with at most 100 spaces 34 * usually less than 100. 35 * @return a randomly generated board filled with icons and widgets. 36 */ generateBoardnull37 open fun generateBoard(width: Int, height: Int, remainingEmptySpaces: Int): CellLayoutBoard { 38 val cellLayoutBoard = CellLayoutBoard(width, height) 39 return fillBoard(cellLayoutBoard, Rect(0, 0, width, height), remainingEmptySpaces) 40 } 41 fillBoardnull42 protected fun fillBoard( 43 board: CellLayoutBoard, 44 area: Rect, 45 remainingEmptySpacesArg: Int 46 ): CellLayoutBoard { 47 var remainingEmptySpaces = remainingEmptySpacesArg 48 if (area.height() * area.width() <= 0) return board 49 val width = getRandom(1, area.width()) 50 val height = getRandom(1, area.height()) 51 val x = area.left + getRandom(0, area.width() - width) 52 val y = area.top + getRandom(0, area.height() - height) 53 if (remainingEmptySpaces > 0) { 54 remainingEmptySpaces -= width * height 55 } 56 57 if (board.widgets.size <= MAX_NUMBER_OF_WIDGETS && width * height > 1) { 58 board.addWidget(x, y, width, height) 59 } else { 60 board.addIcon(x, y) 61 } 62 63 if (remainingEmptySpaces < 0) { 64 // optimization, no need to keep going 65 return board 66 } 67 fillBoard(board, Rect(area.left, area.top, area.right, y), remainingEmptySpaces) 68 fillBoard(board, Rect(area.left, y, x, area.bottom), remainingEmptySpaces) 69 fillBoard(board, Rect(x, y + height, area.right, area.bottom), remainingEmptySpaces) 70 fillBoard(board, Rect(x + width, y, area.right, y + height), remainingEmptySpaces) 71 return board 72 } 73 } 74