1 package com.android.systemui.shared.rotation 2 3 import android.view.Gravity 4 import android.view.Surface 5 6 /** 7 * Calculates gravity and translation that is necessary to display 8 * the button in the correct position based on the current state 9 */ 10 class FloatingRotationButtonPositionCalculator( 11 private val defaultMargin: Int, 12 private val taskbarMarginLeft: Int, 13 private val taskbarMarginBottom: Int, 14 private val floatingRotationButtonPositionLeft: Boolean 15 ) { 16 17 fun calculatePosition( 18 currentRotation: Int, 19 taskbarVisible: Boolean, 20 taskbarStashed: Boolean 21 ): Position { 22 val isTaskbarSide = currentRotation == Surface.ROTATION_0 23 || currentRotation == Surface.ROTATION_90 24 val useTaskbarMargin = isTaskbarSide && taskbarVisible && !taskbarStashed 25 26 val gravity = resolveGravity(currentRotation) 27 28 val marginLeft = if (useTaskbarMargin) taskbarMarginLeft else defaultMargin 29 val marginBottom = if (useTaskbarMargin) taskbarMarginBottom else defaultMargin 30 31 val translationX = 32 if (gravity and Gravity.RIGHT == Gravity.RIGHT) { 33 -marginLeft 34 } else { 35 marginLeft 36 } 37 val translationY = 38 if (gravity and Gravity.BOTTOM == Gravity.BOTTOM) { 39 -marginBottom 40 } else { 41 marginBottom 42 } 43 44 return Position( 45 gravity = gravity, 46 translationX = translationX, 47 translationY = translationY 48 ) 49 } 50 51 data class Position( 52 val gravity: Int, 53 val translationX: Int, 54 val translationY: Int 55 ) 56 57 private fun resolveGravity(rotation: Int): Int = 58 if (floatingRotationButtonPositionLeft) { 59 when (rotation) { 60 Surface.ROTATION_0 -> Gravity.BOTTOM or Gravity.LEFT 61 Surface.ROTATION_90 -> Gravity.BOTTOM or Gravity.RIGHT 62 Surface.ROTATION_180 -> Gravity.TOP or Gravity.RIGHT 63 Surface.ROTATION_270 -> Gravity.TOP or Gravity.LEFT 64 else -> throw IllegalArgumentException("Invalid rotation $rotation") 65 } 66 } else { 67 when (rotation) { 68 Surface.ROTATION_0 -> Gravity.BOTTOM or Gravity.RIGHT 69 Surface.ROTATION_90 -> Gravity.TOP or Gravity.RIGHT 70 Surface.ROTATION_180 -> Gravity.TOP or Gravity.LEFT 71 Surface.ROTATION_270 -> Gravity.BOTTOM or Gravity.LEFT 72 else -> throw IllegalArgumentException("Invalid rotation $rotation") 73 } 74 } 75 } 76