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 17 package android.tools.helpers 18 19 import android.graphics.Insets 20 import android.graphics.Rect 21 import android.tools.Rotation 22 23 /** 24 * A class containing utility methods related to rotation. 25 * 26 * @hide 27 */ 28 object RotationUtils { 29 /** Rotates an Insets according to the given rotation. */ 30 @JvmStatic rotateInsetsnull31 fun rotateInsets(insets: Insets?, rotation: Rotation): Insets { 32 if (insets == null || insets === Insets.NONE) { 33 return Insets.NONE 34 } 35 val rotated = 36 when (rotation) { 37 Rotation.ROTATION_0 -> insets 38 Rotation.ROTATION_90 -> 39 Insets.of(insets.top, insets.right, insets.bottom, insets.left) 40 Rotation.ROTATION_180 -> 41 Insets.of(insets.right, insets.bottom, insets.left, insets.top) 42 Rotation.ROTATION_270 -> 43 Insets.of(insets.bottom, insets.left, insets.top, insets.right) 44 } 45 return rotated 46 } 47 48 /** 49 * Rotates bounds as if parentBounds and bounds are a group. The group is rotated from 50 * oldRotation to newRotation. This assumes that parentBounds is at 0,0 and remains at 0,0 after 51 * rotation. The bounds will be at the same physical position in parentBounds. 52 */ 53 @JvmStatic rotateBoundsnull54 fun rotateBounds( 55 inBounds: Rect, 56 parentBounds: Rect, 57 oldRotation: Rotation, 58 newRotation: Rotation, 59 ): Rect = rotateBounds(inBounds, parentBounds, deltaRotation(oldRotation, newRotation)) 60 61 /** 62 * Rotates inOutBounds together with the parent for a given rotation delta. This assumes that 63 * the parent starts at 0,0 and remains at 0,0 after the rotation. The inOutBounds will remain 64 * at the same physical position within the parent. 65 */ 66 @JvmStatic 67 fun rotateBounds( 68 inBounds: Rect, 69 parentWidth: Int, 70 parentHeight: Int, 71 rotation: Rotation, 72 ): Rect { 73 val origLeft = inBounds.left 74 val origTop = inBounds.top 75 return when (rotation) { 76 Rotation.ROTATION_0 -> inBounds 77 Rotation.ROTATION_90 -> 78 Rect( 79 /* left */ inBounds.top, 80 /* top */ parentWidth - inBounds.right, 81 /* right */ inBounds.bottom, 82 /* bottom */ parentWidth - origLeft, 83 ) 84 Rotation.ROTATION_180 -> 85 Rect( 86 /* left */ parentWidth - inBounds.right, 87 /* right */ parentWidth - origLeft, 88 /* top */ parentHeight - inBounds.bottom, 89 /* bottom */ parentHeight - origTop, 90 ) 91 Rotation.ROTATION_270 -> 92 Rect( 93 /* left */ parentHeight - inBounds.bottom, 94 /* bottom */ inBounds.right, 95 /* right */ parentHeight - inBounds.top, 96 /* top */ origLeft, 97 ) 98 } 99 } 100 101 /** 102 * Rotates bounds as if parentBounds and bounds are a group. The group is rotated by `delta` 103 * 90-degree counter-clockwise increments. This assumes that parentBounds is at 0,0 and remains 104 * at 0,0 after rotation. The bounds will be at the same physical position in parentBounds. 105 */ 106 @JvmStatic rotateBoundsnull107 fun rotateBounds(inBounds: Rect, parentBounds: Rect, rotation: Rotation): Rect = 108 rotateBounds(inBounds, parentBounds.right, parentBounds.bottom, rotation) 109 110 /** @return the rotation needed to rotate from oldRotation to newRotation. */ 111 @JvmStatic 112 fun deltaRotation(oldRotation: Rotation, newRotation: Rotation): Rotation { 113 var delta = newRotation.value - oldRotation.value 114 if (delta < 0) delta += 4 115 return Rotation.getByValue(delta) 116 } 117 } 118