| /* |
| * Copyright 2023 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package androidx.wear.compose.material3 |
| |
| import androidx.compose.animation.core.AnimationSpec |
| import androidx.compose.animation.core.tween |
| import androidx.compose.foundation.background |
| import androidx.compose.foundation.interaction.Interaction |
| import androidx.compose.foundation.interaction.MutableInteractionSource |
| import androidx.compose.foundation.layout.BoxScope |
| import androidx.compose.foundation.layout.IntrinsicSize |
| import androidx.compose.foundation.layout.PaddingValues |
| import androidx.compose.foundation.layout.RowScope |
| import androidx.compose.foundation.layout.defaultMinSize |
| import androidx.compose.foundation.layout.height |
| import androidx.compose.runtime.Composable |
| import androidx.compose.runtime.Immutable |
| import androidx.compose.runtime.State |
| import androidx.compose.runtime.remember |
| import androidx.compose.ui.Modifier |
| import androidx.compose.ui.graphics.Color |
| import androidx.compose.ui.graphics.Shape |
| import androidx.compose.ui.unit.dp |
| import androidx.wear.compose.materialcore.animateSelectionColor |
| |
| /** |
| * The Wear Material [ToggleButton] offers four slots and a specific layout for an icon, a |
| * label, a secondaryLabel and selection control. The icon and secondaryLabel are optional. |
| * The items are laid out in a row with the optional icon at the start, a column containing the two |
| * label slots in the middle and a slot for the selection control at the end. |
| * |
| * The [ToggleButton] is Stadium shaped and has a max height designed to take no more than |
| * two lines of text. |
| * With localisation and/or large font sizes, the [ToggleButton] height adjusts to |
| * accommodate the contents. The label and secondary label should be consistently aligned. |
| * |
| * Samples: |
| * Example of a ToggleButton with a Checkbox: |
| * @sample androidx.wear.compose.material3.samples.ToggleButtonWithCheckbox |
| * |
| * Example of a ToggleButton with a Switch: |
| * @sample androidx.wear.compose.material3.samples.ToggleButtonWithSwitch |
| * |
| * Example of a ToggleButton with a RadioButton: |
| * @sample androidx.wear.compose.material3.samples.ToggleButtonWithRadioButton |
| * |
| * [ToggleButton] can be enabled or disabled. A disabled button will not respond to click events. |
| * |
| * The recommended set of [SplitToggleButton] can be obtained from |
| * [ToggleButtonDefaults], e.g. [ToggleButtonDefaults.toggleButtonColors]. |
| * |
| * @param checked Boolean flag indicating whether this button is currently checked. |
| * @param onCheckedChange Callback to be invoked when this buttons checked/selected status is changed. |
| * @param selectionControl A slot for providing the button's selection control. |
| * Three built-in types of selection control are supported: [Checkbox] ,[RadioButton], and [Switch]. |
| * @param modifier Modifier to be applied to the [ToggleButton]. |
| * @param enabled Controls the enabled state of the button. When `false`, this button will not |
| * be clickable. |
| * @param shape Defines the button's shape. It is strongly recommended to use the default as this |
| * shape is a key characteristic of the Wear Material Theme. |
| * @param colors [ToggleButtonColors] that will be used to resolve the background and |
| * content color for this button in different states. |
| * @param contentPadding The spacing values to apply internally between the container and the |
| * content. |
| * @param interactionSource The [MutableInteractionSource] representing the stream of |
| * [Interaction]s for this button's "toggleable" tap area. You can create and pass in your own |
| * remembered [MutableInteractionSource] if you want to observe [Interaction]s and customize the |
| * appearance / behavior of this Chip in different [Interaction]s. |
| * @param icon An optional slot for providing an icon to indicate the purpose of the button. The |
| * contents are expected to be a horizontally and vertically center aligned icon of size |
| * 24.dp. In order to correctly render when the Chip is not enabled the |
| * icon must set its alpha value to [LocalContentAlpha]. |
| * @param secondaryLabel A slot for providing the button's secondary label. The contents are expected |
| * to be text which is "start" aligned if there is an icon preset and "start" or "center" aligned if |
| * not. label and secondaryLabel contents should be consistently aligned. |
| * @param label A slot for providing the button's main label. The contents are expected to be text |
| * which is "start" aligned if there is an icon preset and "start" or "center" aligned if |
| * not. label and secondaryLabel contents should be consistently aligned. |
| */ |
| @Composable |
| fun ToggleButton( |
| checked: Boolean, |
| onCheckedChange: (Boolean) -> Unit, |
| selectionControl: @Composable () -> Unit, |
| modifier: Modifier = Modifier, |
| enabled: Boolean = true, |
| shape: Shape = MaterialTheme.shapes.large, |
| colors: ToggleButtonColors = ToggleButtonDefaults.toggleButtonColors(), |
| contentPadding: PaddingValues = ToggleButtonDefaults.ContentPadding, |
| interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, |
| icon: @Composable (BoxScope.() -> Unit)? = null, |
| secondaryLabel: @Composable (RowScope.() -> Unit)? = null, |
| label: @Composable RowScope.() -> Unit |
| ) = |
| androidx.wear.compose.materialcore.ToggleButton( |
| checked = checked, |
| onCheckedChange = onCheckedChange, |
| label = provideScopeContent( |
| contentColor = colors.contentColor(enabled = enabled, checked), |
| textStyle = MaterialTheme.typography.labelMedium, |
| content = label |
| ), |
| selectionControl = selectionControl, |
| modifier = modifier |
| .defaultMinSize(minHeight = MIN_HEIGHT) |
| .height(IntrinsicSize.Min), |
| icon = provideNullableScopeContent( |
| contentColor = colors.iconColor(enabled = enabled, checked), |
| content = icon |
| ), |
| secondaryLabel = provideNullableScopeContent( |
| contentColor = colors.secondaryContentColor(enabled = enabled, checked), |
| textStyle = MaterialTheme.typography.labelSmall, |
| content = secondaryLabel |
| ), |
| background = { isEnabled, isChecked -> |
| val backgroundColor = |
| colors.containerColor(enabled = isEnabled, checked = isChecked).value |
| |
| Modifier.background(backgroundColor) |
| }, |
| enabled = enabled, |
| interactionSource = interactionSource, |
| contentPadding = contentPadding, |
| shape = shape, |
| selectionControlWidth = SELECTION_CONTROL_WIDTH, |
| selectionControlHeight = SELECTION_CONTROL_HEIGHT, |
| ripple = rippleOrFallbackImplementation() |
| ) |
| |
| /** |
| * The Wear Material [SplitToggleButton] offers three slots and a specific layout for a label, |
| * secondaryLabel and selection control. The secondaryLabel is optional. The items are laid out |
| * with a column containing the two label slots and a slot for the selection control at the |
| * end. |
| * |
| * The [SplitToggleButton] is Stadium shaped and has a max height designed to take no more than |
| * two lines of text. |
| * With localisation and/or large font sizes, the [SplitToggleButton] height adjusts to |
| * accommodate the contents. The label and secondary label should be consistently aligned. |
| * |
| * A [SplitToggleButton] has two tappable areas, one tap area for the labels and another for the |
| * toggle control. The [onClick] listener will be associated with the main body of the split toggle |
| * button with the [onCheckedChange] listener associated with the toggle control area only. |
| * |
| * Samples: |
| * Example of a SplitToggleButton with a Checkbox: |
| * @sample androidx.wear.compose.material3.samples.SplitToggleButtonWithCheckbox |
| * |
| * Example of a SplitToggleButton with a Switch: |
| * @sample androidx.wear.compose.material3.samples.SplitToggleButtonWithSwitch |
| * |
| * Example of a SplitToggleButton with a RadioButton: |
| * @sample androidx.wear.compose.material3.samples.SplitToggleButtonWithRadioButton |
| * |
| * For a SplitToggleButton the background of the tappable background area behind the selection control |
| * will have a visual effect applied to provide a "divider" between the two tappable areas. |
| * |
| * The recommended set of colors can be obtained from |
| * [ToggleButtonDefaults], e.g. [ToggleButtonDefaults.splitToggleButtonColors]. |
| * |
| * [SplitToggleButton] can be enabled or disabled. A disabled button will not respond to click events. |
| * |
| * @param checked Boolean flag indicating whether this button is currently checked. |
| * @param onCheckedChange Callback to be invoked when this buttons checked/selected status is |
| * changed. |
| * @param onClick Click listener called when the user clicks the main body of the button, the area |
| * behind the labels. |
| * @param selectionControl A slot for providing the button's selection control. |
| * Three built-in types of selection control are supported: [Checkbox] ,[RadioButton], and [Switch]. |
| * @param modifier Modifier to be applied to the button. |
| * @param enabled Controls the enabled state of the button. When `false`, this button will not |
| * be clickable. |
| * @param shape Defines the button's shape. It is strongly recommended to use the default as this |
| * shape is a key characteristic of the Wear Material Theme. |
| * @param colors [SplitToggleButtonColors] that will be used to resolve the background and |
| * content color for this button in different states. |
| * @param contentPadding The spacing values to apply internally between the container and the |
| * content. |
| * @param checkedInteractionSource The [MutableInteractionSource] representing the stream of |
| * [Interaction]s for this button's "toggleable" tap area. You can create and pass in your own |
| * remembered [MutableInteractionSource] if you want to observe [Interaction]s and customize the |
| * appearance / behavior of this button in different [Interaction]s. |
| * @param clickInteractionSource The [MutableInteractionSource] representing the stream of |
| * [Interaction]s for this button's "clickable" tap area. You can create and pass in your own |
| * remembered [MutableInteractionSource] if you want to observe [Interaction]s and customize the |
| * appearance / behavior of this button in different [Interaction]s. |
| * @param secondaryLabel A slot for providing the button's secondary label. The contents are expected |
| * to be "start" or "center" aligned. label and secondaryLabel contents should be consistently |
| * aligned. |
| * @param label A slot for providing the button's main label. The contents are expected to be text |
| * which is "start" aligned if there is an icon preset and "start" or "center" aligned if |
| * not. label and secondaryLabel contents should be consistently aligned. |
| */ |
| @Composable |
| fun SplitToggleButton( |
| checked: Boolean, |
| onCheckedChange: (Boolean) -> Unit, |
| onClick: () -> Unit, |
| selectionControl: @Composable BoxScope.() -> Unit, |
| modifier: Modifier = Modifier, |
| enabled: Boolean = true, |
| shape: Shape = MaterialTheme.shapes.large, |
| colors: SplitToggleButtonColors = ToggleButtonDefaults.splitToggleButtonColors(), |
| checkedInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() }, |
| clickInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() }, |
| contentPadding: PaddingValues = ToggleButtonDefaults.ContentPadding, |
| secondaryLabel: @Composable (RowScope.() -> Unit)? = null, |
| label: @Composable RowScope.() -> Unit |
| ) = androidx.wear.compose.materialcore.SplitToggleButton( |
| checked = checked, |
| onCheckedChange = onCheckedChange, |
| label = provideScopeContent( |
| contentColor = colors.contentColor(enabled = enabled, checked = checked), |
| textStyle = MaterialTheme.typography.labelMedium, |
| content = label |
| ), |
| onClick = onClick, |
| selectionControl = selectionControl, |
| modifier = modifier |
| .defaultMinSize(minHeight = MIN_HEIGHT) |
| .height(IntrinsicSize.Min), |
| secondaryLabel = provideNullableScopeContent( |
| contentColor = colors.secondaryContentColor(enabled = enabled, checked = checked), |
| textStyle = MaterialTheme.typography.labelSmall, |
| content = secondaryLabel |
| ), |
| backgroundColor = { isEnabled, isChecked -> |
| colors.containerColor( |
| enabled = isEnabled, |
| checked = isChecked |
| ) |
| }, |
| splitBackgroundColor = { isEnabled, isChecked -> |
| colors.splitContainerColor( |
| enabled = isEnabled, |
| checked = isChecked |
| ) |
| }, |
| enabled = enabled, |
| checkedInteractionSource = checkedInteractionSource, |
| clickInteractionSource = clickInteractionSource, |
| contentPadding = contentPadding, |
| shape = shape, |
| ripple = rippleOrFallbackImplementation() |
| ) |
| |
| /** |
| * Contains the default values used by [ToggleButton]s and [SplitToggleButton]s |
| */ |
| object ToggleButtonDefaults { |
| |
| /** |
| * Creates a [ToggleButtonColors] for use in a [ToggleButton]. |
| * |
| * @param checkedContainerColor The container color of the [ToggleButton] |
| * when enabled and checked/selected. |
| * @param checkedContentColor The content color of the [ToggleButton] |
| * when enabled and checked/selected. |
| * @param checkedSecondaryContentColor The secondary content color of the [ToggleButton] |
| * when enabled and checked/selected, used for secondaryLabel content. |
| * @param checkedIconColor The icon color of the [ToggleButton] |
| * when enabled and checked/selected. |
| * @param uncheckedContainerColor The container color of the [ToggleButton] |
| * when enabled and unchecked/not selected. |
| * @param uncheckedContentColor The content color of a [ToggleButton] |
| * when enabled and unchecked/not selected. |
| * @param uncheckedSecondaryContentColor The secondary content color of this [ToggleButton] |
| * when enabled and unchecked/not selected, used for secondaryLabel content |
| * @param uncheckedIconColor The icon color of the [ToggleButton] |
| * when enabled and unchecked/not selected. |
| */ |
| @Composable |
| fun toggleButtonColors( |
| checkedContainerColor: Color = MaterialTheme.colorScheme.primaryContainer, |
| checkedContentColor: Color = MaterialTheme.colorScheme.onPrimaryContainer, |
| checkedSecondaryContentColor: Color = MaterialTheme.colorScheme.onPrimaryContainer.copy( |
| alpha = 0.8f |
| ), |
| checkedIconColor: Color = MaterialTheme.colorScheme.onPrimaryContainer, |
| uncheckedContainerColor: Color = MaterialTheme.colorScheme.surface, |
| uncheckedContentColor: Color = MaterialTheme.colorScheme.onSurface, |
| uncheckedSecondaryContentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant, |
| uncheckedIconColor: Color = MaterialTheme.colorScheme.primary, |
| ) = |
| ToggleButtonColors( |
| checkedContainerColor = checkedContainerColor, |
| checkedContentColor = checkedContentColor, |
| checkedSecondaryContentColor = checkedSecondaryContentColor, |
| checkedIconColor = checkedIconColor, |
| uncheckedContainerColor = uncheckedContainerColor, |
| uncheckedContentColor = uncheckedContentColor, |
| uncheckedSecondaryContentColor = uncheckedSecondaryContentColor, |
| uncheckedIconColor = uncheckedIconColor, |
| disabledCheckedContainerColor = checkedContainerColor.toDisabledColor(), |
| disabledCheckedContentColor = checkedContentColor.toDisabledColor(), |
| disabledCheckedSecondaryContentColor = checkedSecondaryContentColor.toDisabledColor(), |
| disabledCheckedIconColor = checkedIconColor.toDisabledColor(), |
| disabledUncheckedContainerColor = uncheckedContainerColor.toDisabledColor(), |
| disabledUncheckedContentColor = uncheckedContentColor.toDisabledColor(), |
| disabledUncheckedSecondaryContentColor = |
| uncheckedSecondaryContentColor.toDisabledColor(), |
| disabledUncheckedIconColor = uncheckedIconColor.toDisabledColor(), |
| ) |
| |
| /** |
| * Creates a [SplitToggleButtonColors] for use in a [SplitToggleButton]. |
| * |
| * @param checkedContainerColor The container color of the [SplitToggleButton] when enabled and |
| * checked/selected. |
| * @param checkedContentColor The content color of the [SplitToggleButton] when enabled and |
| * checked/selected. |
| * @param checkedSecondaryContentColor The secondary content color of the [SplitToggleButton] |
| * when enabled and checked/selected, used for secondaryLabel content. |
| * @param checkedSplitContainerColor The split container color of the [SplitToggleButton] |
| * when enabled and checked/selected. |
| * @param uncheckedContainerColor The container color of the [SplitToggleButton] when enabled |
| * and unchecked/not selected. |
| * @param uncheckedContentColor The content color of the [SplitToggleButton] when enabled and |
| * unchecked/not selected. |
| * @param uncheckedSecondaryContentColor The secondary content color of the [SplitToggleButton] |
| * when enabled and unchecked/not selected, used for secondaryLabel content. |
| * @param uncheckedSplitContainerColor The split container color of the [SplitToggleButton] when |
| * enabled and unchecked/not selected. |
| */ |
| @Composable |
| fun splitToggleButtonColors( |
| checkedContainerColor: Color = MaterialTheme.colorScheme.primaryContainer, |
| checkedContentColor: Color = MaterialTheme.colorScheme.onPrimaryContainer, |
| checkedSecondaryContentColor: Color = MaterialTheme.colorScheme.onPrimaryContainer.copy( |
| alpha = 0.8f |
| ), |
| checkedSplitContainerColor: Color = MaterialTheme.colorScheme.primary.copy(.15f), |
| uncheckedContainerColor: Color = MaterialTheme.colorScheme.surface, |
| uncheckedContentColor: Color = MaterialTheme.colorScheme.onSurface, |
| uncheckedSecondaryContentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant, |
| uncheckedSplitContainerColor: Color = MaterialTheme.colorScheme.surfaceBright |
| ) = |
| SplitToggleButtonColors( |
| checkedContainerColor = checkedContainerColor, |
| checkedContentColor = checkedContentColor, |
| checkedSecondaryContentColor = checkedSecondaryContentColor, |
| checkedSplitContainerColor = checkedSplitContainerColor, |
| uncheckedContainerColor = uncheckedContainerColor, |
| uncheckedContentColor = uncheckedContentColor, |
| uncheckedSecondaryContentColor = uncheckedSecondaryContentColor, |
| uncheckedSplitContainerColor = uncheckedSplitContainerColor, |
| disabledCheckedContainerColor = checkedContainerColor.toDisabledColor(), |
| disabledCheckedContentColor = checkedContentColor.toDisabledColor(), |
| disabledCheckedSecondaryContentColor = checkedSecondaryContentColor.toDisabledColor(), |
| disabledCheckedSplitContainerColor = checkedSplitContainerColor.toDisabledColor(), |
| disabledUncheckedContainerColor = uncheckedContainerColor.toDisabledColor(), |
| disabledUncheckedContentColor = uncheckedContentColor.toDisabledColor(), |
| disabledUncheckedSecondaryContentColor = |
| uncheckedSecondaryContentColor.toDisabledColor(), |
| disabledUncheckedSplitContainerColor = uncheckedSplitContainerColor.toDisabledColor() |
| ) |
| |
| private val ChipHorizontalPadding = 14.dp |
| private val ChipVerticalPadding = 6.dp |
| |
| val ContentPadding: PaddingValues = PaddingValues( |
| start = ChipHorizontalPadding, |
| top = ChipVerticalPadding, |
| end = ChipHorizontalPadding, |
| bottom = ChipVerticalPadding |
| ) |
| } |
| |
| /** |
| * Represents the different container and content colors used for toggle buttons |
| * ([ToggleButton], [IconToggleButton], and [TextToggleButton]) in various states, |
| * that are checked, unchecked, enabled and disabled. |
| * |
| * @constructor [ToggleButtonColors] constructor to be used with [ToggleButton] |
| * @param checkedContainerColor Container or background color when the toggle button is checked |
| * @param checkedContentColor Color of the content like label when the toggle button is checked |
| * @param checkedSecondaryContentColor Color of the secondary content like secondary label when the |
| * toggle button is checked |
| * @param checkedIconColor Color of the icon when the toggle button is checked |
| * @param uncheckedContainerColor Container or background color when the toggle button is unchecked |
| * @param uncheckedContentColor Color of the content like label when the toggle button is unchecked |
| * @param uncheckedSecondaryContentColor Color of the secondary content like secondary label when |
| * the toggle button is unchecked |
| * @param uncheckedIconColor Color of the icon when the toggle button is unchecked |
| * @param disabledCheckedContainerColor Container or background color when the toggle button is |
| * disabled and checked |
| * @param disabledCheckedContentColor Color of content like label when the toggle button is |
| * disabled and checked |
| * @param disabledCheckedSecondaryContentColor Color of the secondary content like secondary label |
| * when the toggle button is disabled and checked |
| * @param disabledCheckedIconColor Icon color when the toggle button is disabled and checked |
| * @param disabledUncheckedContainerColor Container or background color when the toggle button is |
| * disabled and unchecked |
| * @param disabledUncheckedContentColor Color of the content like label when the toggle button is |
| * disabled and unchecked |
| * @param disabledUncheckedSecondaryContentColor Color of the secondary content like secondary label |
| * when the toggle button is disabled and unchecked |
| * @param disabledUncheckedIconColor Icon color when the toggle button is disabled and unchecked |
| */ |
| @Immutable |
| class ToggleButtonColors constructor( |
| val checkedContainerColor: Color, |
| val checkedContentColor: Color, |
| val checkedSecondaryContentColor: Color, |
| val checkedIconColor: Color, |
| val uncheckedContainerColor: Color, |
| val uncheckedContentColor: Color, |
| val uncheckedSecondaryContentColor: Color, |
| val uncheckedIconColor: Color, |
| val disabledCheckedContainerColor: Color, |
| val disabledCheckedContentColor: Color, |
| val disabledCheckedSecondaryContentColor: Color, |
| val disabledCheckedIconColor: Color, |
| val disabledUncheckedContainerColor: Color, |
| val disabledUncheckedContentColor: Color, |
| val disabledUncheckedSecondaryContentColor: Color, |
| val disabledUncheckedIconColor: Color, |
| ) { |
| /** |
| * [ToggleButtonColors] constructor for [IconToggleButton] and [TextToggleButton]. |
| * |
| * @param checkedContainerColor Container or background color of the toggle button when checked |
| * @param checkedContentColor Color of the content (text or icon) of the toggle button when |
| * checked |
| * @param uncheckedContainerColor Container or background color of the toggle button when |
| * unchecked |
| * @param uncheckedContentColor Color of the content (text or icon) of the toggle button when |
| * unchecked |
| * @param disabledCheckedContainerColor Container or background color of the toggle button when |
| * disabled and checked |
| * @param disabledCheckedContentColor Color of the content (icon or text) toggle button when |
| * disabled and unchecked |
| * @param disabledUncheckedContainerColor Container or background color of the toggle button |
| * when disabled and unchecked |
| * @param disabledUncheckedContentColor Color of the content (icon or text) toggle button when |
| * disabled and unchecked |
| */ |
| constructor( |
| checkedContainerColor: Color, |
| checkedContentColor: Color, |
| uncheckedContainerColor: Color, |
| uncheckedContentColor: Color, |
| disabledCheckedContainerColor: Color, |
| disabledCheckedContentColor: Color, |
| disabledUncheckedContainerColor: Color, |
| disabledUncheckedContentColor: Color |
| ) : this( |
| checkedContainerColor = checkedContainerColor, |
| checkedContentColor = checkedContentColor, |
| checkedSecondaryContentColor = checkedContainerColor, |
| checkedIconColor = checkedContentColor, |
| uncheckedContainerColor = uncheckedContainerColor, |
| uncheckedContentColor = uncheckedContentColor, |
| uncheckedSecondaryContentColor = uncheckedContentColor, |
| uncheckedIconColor = uncheckedContentColor, |
| disabledCheckedContainerColor = disabledCheckedContainerColor, |
| disabledCheckedContentColor = disabledCheckedContentColor, |
| disabledCheckedSecondaryContentColor = disabledCheckedContentColor, |
| disabledCheckedIconColor = disabledCheckedContentColor, |
| disabledUncheckedContainerColor = disabledUncheckedContainerColor, |
| disabledUncheckedContentColor = disabledUncheckedContentColor, |
| disabledUncheckedSecondaryContentColor = disabledUncheckedContentColor, |
| disabledUncheckedIconColor = disabledUncheckedContentColor, |
| ) |
| |
| /** |
| * Determines the container color based on whether the toggle button is [enabled] |
| * and [checked]. |
| * |
| * @param enabled Whether the toggle button is enabled |
| * @param checked Whether the toggle button is checked |
| */ |
| @Composable |
| fun containerColor(enabled: Boolean, checked: Boolean): State<Color> = |
| animateSelectionColor( |
| enabled = enabled, |
| checked = checked, |
| checkedColor = checkedContainerColor, |
| uncheckedColor = uncheckedContainerColor, |
| disabledCheckedColor = disabledCheckedContainerColor, |
| disabledUncheckedColor = disabledUncheckedContainerColor, |
| animationSpec = COLOR_ANIMATION_SPEC |
| ) |
| |
| /** |
| * Determines the content color based on whether the toggle button is [enabled] |
| * and [checked]. |
| * |
| * @param enabled Whether the toggle button is enabled |
| * @param checked Whether the toggle button is checked |
| */ |
| @Composable |
| fun contentColor(enabled: Boolean, checked: Boolean): State<Color> = |
| animateSelectionColor( |
| enabled = enabled, |
| checked = checked, |
| checkedColor = checkedContentColor, |
| uncheckedColor = uncheckedContentColor, |
| disabledCheckedColor = disabledCheckedContentColor, |
| disabledUncheckedColor = disabledUncheckedContentColor, |
| animationSpec = COLOR_ANIMATION_SPEC |
| ) |
| |
| /** |
| * Represents the secondary content color depending on the [enabled] and [checked] properties. |
| * |
| * @param enabled Whether the ToggleButton is enabled. |
| * @param checked Whether the ToggleButton is currently checked/selected |
| * or unchecked/not selected. |
| */ |
| @Composable |
| fun secondaryContentColor(enabled: Boolean, checked: Boolean): State<Color> = |
| animateSelectionColor( |
| enabled = enabled, |
| checked = checked, |
| checkedColor = checkedSecondaryContentColor, |
| uncheckedColor = uncheckedSecondaryContentColor, |
| disabledCheckedColor = disabledCheckedSecondaryContentColor, |
| disabledUncheckedColor = disabledUncheckedSecondaryContentColor, |
| animationSpec = COLOR_ANIMATION_SPEC |
| ) |
| |
| /** |
| * Represents the icon color for the [ToggleButton] depending on the |
| * [enabled] and [checked] properties. |
| * |
| * @param enabled Whether the ToggleButton is enabled. |
| * @param checked Whether the ToggleButton is currently checked/selected |
| * or unchecked/not selected. |
| */ |
| @Composable |
| fun iconColor(enabled: Boolean, checked: Boolean): State<Color> = |
| animateSelectionColor( |
| enabled = enabled, |
| checked = checked, |
| checkedColor = checkedIconColor, |
| uncheckedColor = uncheckedIconColor, |
| disabledCheckedColor = disabledCheckedIconColor, |
| disabledUncheckedColor = disabledUncheckedIconColor, |
| animationSpec = COLOR_ANIMATION_SPEC |
| ) |
| |
| override fun equals(other: Any?): Boolean { |
| if (this === other) return true |
| if (other == null) return false |
| if (this::class != other::class) return false |
| |
| other as ToggleButtonColors |
| |
| if (checkedContainerColor != other.checkedContainerColor) return false |
| if (checkedContentColor != other.checkedContentColor) return false |
| if (checkedSecondaryContentColor != other.checkedSecondaryContentColor) return false |
| if (checkedIconColor != other.checkedIconColor) return false |
| if (uncheckedContainerColor != other.uncheckedContainerColor) return false |
| if (uncheckedContentColor != other.uncheckedContentColor) return false |
| if (uncheckedSecondaryContentColor != other.uncheckedSecondaryContentColor) return false |
| if (uncheckedIconColor != other.uncheckedIconColor) return false |
| if (disabledCheckedContainerColor != other.disabledCheckedContainerColor) return false |
| if (disabledCheckedContentColor != other.disabledCheckedContentColor) return false |
| if (disabledCheckedSecondaryContentColor != |
| other.disabledCheckedSecondaryContentColor |
| ) return false |
| if (disabledCheckedIconColor != other.disabledCheckedIconColor) return false |
| if (disabledUncheckedContainerColor != other.disabledUncheckedContainerColor) return false |
| if (disabledUncheckedContentColor != other.disabledUncheckedContentColor) return false |
| if (disabledUncheckedSecondaryContentColor != |
| other.disabledUncheckedSecondaryContentColor |
| ) return false |
| if (disabledUncheckedIconColor != other.disabledUncheckedIconColor) |
| return false |
| |
| return true |
| } |
| |
| override fun hashCode(): Int { |
| var result = checkedContainerColor.hashCode() |
| result = 31 * result + checkedContentColor.hashCode() |
| result = 31 * result + checkedSecondaryContentColor.hashCode() |
| result = 31 * result + checkedIconColor.hashCode() |
| result = 31 * result + uncheckedContainerColor.hashCode() |
| result = 31 * result + uncheckedContentColor.hashCode() |
| result = 31 * result + uncheckedSecondaryContentColor.hashCode() |
| result = 31 * result + uncheckedIconColor.hashCode() |
| result = 31 * result + disabledCheckedContainerColor.hashCode() |
| result = 31 * result + disabledCheckedContentColor.hashCode() |
| result = 31 * result + disabledCheckedSecondaryContentColor.hashCode() |
| result = 31 * result + disabledCheckedIconColor.hashCode() |
| result = 31 * result + disabledUncheckedContainerColor.hashCode() |
| result = 31 * result + disabledUncheckedContentColor.hashCode() |
| result = 31 * result + disabledUncheckedSecondaryContentColor.hashCode() |
| result = 31 * result + disabledUncheckedIconColor.hashCode() |
| return result |
| } |
| } |
| |
| /** |
| * Represents the different colors used in [SplitToggleButton] in different states. |
| * |
| * @constructor [SplitToggleButtonColors] constructor to be used with [SplitToggleButton] |
| * @param checkedContainerColor Container or background color when the split toggle button is |
| * checked |
| * @param checkedContentColor Color of the content like label when the split toggle button is |
| * checked |
| * @param checkedSecondaryContentColor Color of the secondary content like secondary label when the |
| * split toggle button is checked |
| * @param checkedSplitContainerColor Split container color when the split toggle button is checked |
| * @param uncheckedContainerColor Container or background color when the split toggle button is |
| * unchecked |
| * @param uncheckedContentColor Color of the content like label when the split toggle button is |
| * unchecked |
| * @param uncheckedSecondaryContentColor Color of the secondary content like secondary label when |
| * the split toggle button is unchecked |
| * @param uncheckedSplitContainerColor Split container color when the split toggle button is |
| * unchecked |
| * @param disabledCheckedContainerColor Container color when the split toggle button is disabled |
| * and checked |
| * @param disabledCheckedContentColor Color of the content like label when the split toggle button |
| * is disabled and checked |
| * @param disabledCheckedSecondaryContentColor Color of the secondary content like secondary label |
| * when the split toggle button is disabled and checked |
| * @param disabledCheckedSplitContainerColor Split container color when the split toggle button is |
| * disabled and checked |
| * @param disabledUncheckedContainerColor Container color when the split toggle button is unchecked |
| * and disabled |
| * @param disabledUncheckedContentColor Color of the content like label when the split toggle |
| * button is unchecked and disabled |
| * @param disabledUncheckedSecondaryContentColor Color of the secondary content like secondary |
| * label when the split toggle button is unchecked and disabled |
| * @param disabledUncheckedSplitContainerColor Split container color when the split toggle button |
| * is unchecked and disabled |
| */ |
| class SplitToggleButtonColors constructor( |
| val checkedContainerColor: Color, |
| val checkedContentColor: Color, |
| val checkedSecondaryContentColor: Color, |
| val checkedSplitContainerColor: Color, |
| val uncheckedContainerColor: Color, |
| val uncheckedContentColor: Color, |
| val uncheckedSecondaryContentColor: Color, |
| val uncheckedSplitContainerColor: Color, |
| val disabledCheckedContainerColor: Color, |
| val disabledCheckedContentColor: Color, |
| val disabledCheckedSecondaryContentColor: Color, |
| val disabledCheckedSplitContainerColor: Color, |
| val disabledUncheckedContainerColor: Color, |
| val disabledUncheckedContentColor: Color, |
| val disabledUncheckedSecondaryContentColor: Color, |
| val disabledUncheckedSplitContainerColor: Color, |
| ) { |
| |
| /** |
| * Determines the container color based on whether the [SplitToggleButton] is [enabled] |
| * and [checked]. |
| * |
| * @param enabled Whether the [SplitToggleButton] is enabled |
| * @param checked Whether the [SplitToggleButton] is currently checked/selected |
| */ |
| @Composable |
| internal fun containerColor(enabled: Boolean, checked: Boolean): State<Color> = |
| animateSelectionColor( |
| enabled = enabled, |
| checked = checked, |
| checkedColor = checkedContainerColor, |
| uncheckedColor = uncheckedContainerColor, |
| disabledCheckedColor = disabledCheckedContainerColor, |
| disabledUncheckedColor = disabledUncheckedContainerColor, |
| animationSpec = COLOR_ANIMATION_SPEC |
| ) |
| |
| /** |
| * Determines the content color based on whether the [SplitToggleButton] is [enabled] |
| * and [checked]. |
| * |
| * @param enabled Whether the [SplitToggleButton] is enabled |
| * @param checked Whether the [SplitToggleButton] is currently checked/selected |
| */ |
| @Composable |
| internal fun contentColor(enabled: Boolean, checked: Boolean): State<Color> = |
| animateSelectionColor( |
| enabled = enabled, |
| checked = checked, |
| checkedColor = checkedContentColor, |
| uncheckedColor = uncheckedContentColor, |
| disabledCheckedColor = disabledCheckedContentColor, |
| disabledUncheckedColor = disabledUncheckedContentColor, |
| animationSpec = COLOR_ANIMATION_SPEC |
| ) |
| |
| /** |
| * Represents the secondary content color for the [SplitToggleButton] depending on the |
| * [enabled] and [checked] properties. |
| * |
| * @param enabled Whether the [SplitToggleButton] is enabled. |
| * @param checked Whether the [SplitToggleButton] is currently checked/selected |
| * or unchecked/not selected. |
| */ |
| @Composable |
| internal fun secondaryContentColor(enabled: Boolean, checked: Boolean): State<Color> = |
| animateSelectionColor( |
| enabled = enabled, |
| checked = checked, |
| checkedColor = checkedSecondaryContentColor, |
| uncheckedColor = uncheckedSecondaryContentColor, |
| disabledCheckedColor = disabledCheckedSecondaryContentColor, |
| disabledUncheckedColor = disabledUncheckedSecondaryContentColor, |
| animationSpec = COLOR_ANIMATION_SPEC |
| ) |
| |
| /** |
| * Represents the split container for the [SplitToggleButton] color depending on the |
| * [enabled] and [checked] properties. |
| * |
| * @param enabled Whether the [SplitToggleButton] is enabled. |
| * @param checked Whether the [SplitToggleButton] is currently checked/selected |
| * or unchecked/not selected. |
| */ |
| @Composable |
| fun splitContainerColor(enabled: Boolean, checked: Boolean): State<Color> = |
| animateSelectionColor( |
| enabled = enabled, |
| checked = checked, |
| checkedColor = checkedSplitContainerColor, |
| uncheckedColor = uncheckedSplitContainerColor, |
| disabledCheckedColor = disabledCheckedSplitContainerColor, |
| disabledUncheckedColor = disabledUncheckedSplitContainerColor, |
| animationSpec = COLOR_ANIMATION_SPEC |
| ) |
| |
| override fun equals(other: Any?): Boolean { |
| if (this === other) return true |
| if (other == null) return false |
| if (this::class != other::class) return false |
| |
| other as SplitToggleButtonColors |
| |
| if (checkedContainerColor != other.checkedContainerColor) return false |
| if (checkedContentColor != other.checkedContentColor) return false |
| if (checkedSecondaryContentColor != other.checkedSecondaryContentColor) return false |
| if (checkedSplitContainerColor != other.checkedSplitContainerColor) return false |
| if (uncheckedContainerColor != other.uncheckedContainerColor) return false |
| if (uncheckedContentColor != other.uncheckedContentColor) return false |
| if (uncheckedSecondaryContentColor != other.uncheckedSecondaryContentColor) return false |
| if (uncheckedSplitContainerColor != other.uncheckedSplitContainerColor) return false |
| if (disabledCheckedContainerColor != other.disabledCheckedContainerColor) return false |
| if (disabledCheckedContentColor != other.disabledCheckedContentColor) return false |
| if (disabledCheckedSecondaryContentColor != |
| other.disabledCheckedSecondaryContentColor |
| ) return false |
| if (disabledCheckedSplitContainerColor != other.disabledCheckedSplitContainerColor) |
| return false |
| if (disabledUncheckedContainerColor != other.disabledUncheckedContainerColor) return false |
| if (disabledUncheckedContentColor != other.disabledUncheckedContentColor) return false |
| if (disabledUncheckedSecondaryContentColor != |
| other.disabledUncheckedSecondaryContentColor |
| ) return false |
| if (disabledUncheckedSplitContainerColor != other.disabledUncheckedSplitContainerColor) |
| return false |
| |
| return true |
| } |
| |
| override fun hashCode(): Int { |
| var result = checkedContainerColor.hashCode() |
| result = 31 * result + checkedContentColor.hashCode() |
| result = 31 * result + checkedSecondaryContentColor.hashCode() |
| result = 31 * result + checkedSplitContainerColor.hashCode() |
| result = 31 * result + uncheckedContainerColor.hashCode() |
| result = 31 * result + uncheckedContentColor.hashCode() |
| result = 31 * result + uncheckedSecondaryContentColor.hashCode() |
| result = 31 * result + uncheckedSplitContainerColor.hashCode() |
| result = 31 * result + disabledCheckedContainerColor.hashCode() |
| result = 31 * result + disabledCheckedContentColor.hashCode() |
| result = 31 * result + disabledCheckedSecondaryContentColor.hashCode() |
| result = 31 * result + disabledCheckedSplitContainerColor.hashCode() |
| result = 31 * result + disabledUncheckedContainerColor.hashCode() |
| result = 31 * result + disabledUncheckedContentColor.hashCode() |
| result = 31 * result + disabledUncheckedSecondaryContentColor.hashCode() |
| result = 31 * result + disabledUncheckedSplitContainerColor.hashCode() |
| return result |
| } |
| } |
| |
| private val SELECTION_CONTROL_WIDTH = 32.dp |
| private val SELECTION_CONTROL_HEIGHT = 24.dp |
| private val MIN_HEIGHT = 52.dp |
| |
| private val COLOR_ANIMATION_SPEC: AnimationSpec<Color> = |
| tween(MEDIUM_1, 0, STANDARD_DECELERATE) |