1 /* 2 * Copyright (C) 2025 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 com.android.systemui.statusbar.pipeline.battery.shared.ui 18 19 import androidx.compose.ui.graphics.Path 20 import androidx.compose.ui.graphics.addSvg 21 import androidx.compose.ui.unit.Dp 22 import androidx.compose.ui.unit.dp 23 import kotlin.math.min 24 25 /** Instead of reading from xml, we can define the battery here with a single Path */ 26 object BatteryFrame { 27 val pathSpec = 28 PathSpec( 29 path = <lambda>null30 Path().apply { 31 addSvg( 32 "M17.5 0H2C0.895431 0 0 0.895431 0 2V10C0 11.1046 0.89543 12 2 12H17.5C18.6046 12 19.5 11.1046 19.5 10V8H19.9231C20.5178 8 21 7.51785 21 6.92308V5.07692C21 4.48215 20.5178 4 19.9231 4H19.5V2C19.5 0.895431 18.6046 0 17.5 0Z" 33 ) 34 }, 35 viewportHeight = 12.dp, 36 viewportWidth = 21.dp, 37 ) 38 39 /** The width of the drawable that is usable for inside elements */ 40 const val innerWidth = 19.5f 41 42 /** The height of the drawable that is usable for inside elements */ 43 const val innerHeight = 12f 44 } 45 46 /** 47 * Encapsulates both the [Path] and the drawn dimensions of the internal SVG path. Use [scaleTo] to 48 * determine the appropriate scale factor (x and y) to fit the frame into its container 49 */ 50 data class PathSpec(val path: Path, val viewportWidth: Dp, val viewportHeight: Dp) { 51 /** Return the appropriate scale to achieve FIT_CENTER-type scaling */ scaleTonull52 fun scaleTo(w: Float, h: Float): Float { 53 // FIT_CENTER for the path, this determines how much we need to scale up to fit the bounds 54 // without skewing 55 val xScale = w / viewportWidth.value 56 val yScale = h / viewportHeight.value 57 58 return min(xScale, yScale) 59 } 60 } 61