1 /* 2 * Copyright 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 androidx.wear.protolayout.material3 18 19 import androidx.annotation.Dimension 20 import androidx.annotation.Dimension.Companion.DP 21 import androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters 22 import androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec 23 import androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing 24 import androidx.wear.protolayout.types.LayoutColor 25 26 /** 27 * Represents the indicator and track colors used in progress indicator. 28 * 29 * @param indicatorColor Color used to draw the indicator of progress indicator. 30 * @param trackColor Color used to draw the track of progress indicator. 31 * @param trackOverflowColor Color used to draw the track for progress overflow (>1). 32 */ 33 public class ProgressIndicatorColors( 34 public val indicatorColor: LayoutColor, 35 public val trackColor: LayoutColor, 36 public val trackOverflowColor: LayoutColor = trackColor 37 ) { 38 /** 39 * Returns a copy of this [ProgressIndicatorColors], optionally overriding some of the values. 40 * 41 * @param indicatorColor Color used to draw the indicator of progress indicator. 42 * @param trackColor Color used to draw the track of progress indicator. 43 * @param trackOverflowColor Color used to draw the track for progress overflow (>1). 44 */ copynull45 public fun copy( 46 indicatorColor: LayoutColor = this.indicatorColor, 47 trackColor: LayoutColor = this.trackColor, 48 trackOverflowColor: LayoutColor = this.trackOverflowColor 49 ): ProgressIndicatorColors = 50 ProgressIndicatorColors( 51 indicatorColor = indicatorColor, 52 trackColor = trackColor, 53 trackOverflowColor = trackOverflowColor 54 ) 55 } 56 57 public object CircularProgressIndicatorDefaults { 58 /** 59 * Returns the recommended [ProgressIndicatorColors] object to be used when placing the progress 60 * indicator inside a graphic card with [CardDefaults.filledCardColors] from the given 61 * [MaterialScope]'s [ColorScheme]. 62 */ 63 public fun MaterialScope.filledProgressIndicatorColors(): ProgressIndicatorColors = 64 ProgressIndicatorColors( 65 theme.colorScheme.onPrimary, 66 theme.colorScheme.onPrimary.withOpacity(0.2F), 67 theme.colorScheme.onPrimary.withOpacity(0.6F) 68 ) 69 70 /** 71 * Returns the recommended [ProgressIndicatorColors] object to be used when placing the progress 72 * indicator inside a graphic card with [CardDefaults.filledTonalCardColors] from the given 73 * [MaterialScope]'s [ColorScheme]. 74 */ 75 public fun MaterialScope.filledTonalProgressIndicatorColors(): ProgressIndicatorColors = 76 ProgressIndicatorColors( 77 theme.colorScheme.primary, 78 theme.colorScheme.primary.withOpacity(0.2F), 79 theme.colorScheme.primary.withOpacity(0.6F) 80 ) 81 82 /** 83 * Returns the recommended [ProgressIndicatorColors] object to be used when placing the progress 84 * indicator inside a graphic card with [CardDefaults.filledVariantCardColors] from the given 85 * [MaterialScope]'s [ColorScheme]. 86 */ 87 public fun MaterialScope.filledVariantProgressIndicatorColors(): ProgressIndicatorColors = 88 ProgressIndicatorColors( 89 theme.colorScheme.onPrimaryContainer, 90 theme.colorScheme.onPrimaryContainer.withOpacity(0.2F), 91 theme.colorScheme.onPrimaryContainer.withOpacity(0.6F), 92 ) 93 94 /** 95 * The recommended animation spec for animations from current progress to a new progress value. 96 */ 97 public val recommendedAnimationSpec: AnimationSpec = 98 AnimationSpec.Builder() 99 .setAnimationParameters( 100 AnimationParameters.Builder() 101 .setDurationMillis(450) 102 .setEasing(Easing.cubicBezier(0.2f, 0f, 0f, 1f)) 103 .build() 104 ) 105 .build() 106 107 /** Large stroke width for circular progress indicator. */ 108 @Dimension(DP) public const val LARGE_STROKE_WIDTH: Float = 8F 109 110 /** Small stroke width for circular progress indicator. */ 111 @Dimension(DP) public const val SMALL_STROKE_WIDTH: Float = 4F 112 113 /** 114 * Returns recommended size of the gap based on [strokeWidth]. 115 * 116 * The absolute value can be customized with `gapSize` parameter on [circularProgressIndicator]. 117 */ 118 @Dimension(DP) 119 public fun calculateRecommendedGapSize(@Dimension(DP) strokeWidth: Float): Float = 120 strokeWidth / 3F 121 122 internal const val METADATA_TAG: String = "M3CPI" 123 /** 124 * A small offset to make the progress arc remaining when the progress is 1, with the module 125 * operation applied for handling overflow. 126 */ 127 internal const val TRIVIAL_ARC_OFFSET: Float = 0.05f 128 129 /** 130 * Extra stroke width for progress arc to prevent aliasing issue where the progress arc draws on 131 * top of the track arc where there are multiple segments. 132 */ 133 internal const val INDICATOR_STROKE_WIDTH_INCREMENT_PX: Float = 1.5f 134 135 /** 136 * Extra gap size in pixels between track arc segments to make the each track arc segment 137 * slightly shorter than the indicator arc segment on its top, so that it can be fully covered 138 * by the indicator on segment ends to prevent aliasing issue. 139 */ 140 internal const val TRACK_GAP_SIZE_INCREMENT_PX: Float = 1f 141 142 /** Default size for the fallback implementation. */ 143 @Dimension(DP) internal const val CPI_DEFAULT_DP_SIZE: Float = 52F 144 } 145