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. */ rotateInsetsnull30 fun rotateInsets(insets: Insets?, rotation: Rotation): Insets { 31 if (insets == null || insets === Insets.NONE) { 32 return Insets.NONE 33 } 34 val rotated = 35 when (rotation) { 36 Rotation.ROTATION_0 -> insets 37 Rotation.ROTATION_90 -> 38 Insets.of(insets.top, insets.right, insets.bottom, insets.left) 39 Rotation.ROTATION_180 -> 40 Insets.of(insets.right, insets.bottom, insets.left, insets.top) 41 Rotation.ROTATION_270 -> 42 Insets.of(insets.bottom, insets.left, insets.top, insets.right) 43 } 44 return rotated 45 } 46 47 /** 48 * Rotates bounds as if parentBounds and bounds are a group. The group is rotated from 49 * oldRotation to newRotation. This assumes that parentBounds is at 0,0 and remains at 0,0 after 50 * rotation. The bounds will be at the same physical position in parentBounds. 51 */ rotateBoundsnull52 fun rotateBounds( 53 inBounds: Rect, 54 parentBounds: Rect, 55 oldRotation: Rotation, 56 newRotation: Rotation 57 ): Rect = rotateBounds(inBounds, parentBounds, deltaRotation(oldRotation, newRotation)) 58 59 /** 60 * Rotates inOutBounds together with the parent for a given rotation delta. This assumes that 61 * the parent starts at 0,0 and remains at 0,0 after the rotation. The inOutBounds will remain 62 * at the same physical position within the parent. 63 */ 64 fun rotateBounds( 65 inBounds: Rect, 66 parentWidth: Int, 67 parentHeight: Int, 68 rotation: Rotation 69 ): Rect { 70 val origLeft = inBounds.left 71 val origTop = inBounds.top 72 return when (rotation) { 73 Rotation.ROTATION_0 -> inBounds 74 Rotation.ROTATION_90 -> 75 Rect( 76 /* left */ inBounds.top, 77 /* top */ parentWidth - inBounds.right, 78 /* right */ inBounds.bottom, 79 /* bottom */ parentWidth - origLeft 80 ) 81 Rotation.ROTATION_180 -> 82 Rect( 83 /* left */ parentWidth - inBounds.right, 84 /* right */ parentWidth - origLeft, 85 /* top */ parentHeight - inBounds.bottom, 86 /* bottom */ parentHeight - origTop 87 ) 88 Rotation.ROTATION_270 -> 89 Rect( 90 /* left */ parentHeight - inBounds.bottom, 91 /* bottom */ inBounds.right, 92 /* right */ parentHeight - inBounds.top, 93 /* top */ origLeft 94 ) 95 } 96 } 97 98 /** 99 * Rotates bounds as if parentBounds and bounds are a group. The group is rotated by `delta` 100 * 90-degree counter-clockwise increments. This assumes that parentBounds is at 0,0 and remains 101 * at 0,0 after rotation. The bounds will be at the same physical position in parentBounds. 102 */ rotateBoundsnull103 fun rotateBounds(inBounds: Rect, parentBounds: Rect, rotation: Rotation): Rect = 104 rotateBounds(inBounds, parentBounds.right, parentBounds.bottom, rotation) 105 106 /** @return the rotation needed to rotate from oldRotation to newRotation. */ 107 fun deltaRotation(oldRotation: Rotation, newRotation: Rotation): Rotation { 108 var delta = newRotation.value - oldRotation.value 109 if (delta < 0) delta += 4 110 return Rotation.getByValue(delta) 111 } 112 } 113