Replace the color / text style tokens with the newly defined picker specific tokens

Also minor adjustments on where color is applied vs clipping / scroll modifiers are applied.

Bug: 408283627
Flag: EXEMPT independent module
Test: See demo
Change-Id: Ie5270f27d6cb8a6fc1984d6421937b1d8763aee9
This commit is contained in:
Shamali Patwa
2025-06-03 06:00:26 -07:00
parent 7423dafef0
commit ceccd4a155
15 changed files with 104 additions and 227 deletions
@@ -24,21 +24,18 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.KeyboardArrowDown
import androidx.compose.material.icons.rounded.KeyboardArrowUp
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.android.launcher3.widgetpicker.ui.theme.WidgetPickerTheme
/** A visual cue displayed on list headers to indicate its current expand / collapse state. */
@Composable
fun ExpandCollapseIndicator(
expanded: Boolean,
modifier: Modifier = Modifier,
iconColor: Color = ExpandCollapseIndicatorDefaults.iconColor,
backgroundColor: Color = ExpandCollapseIndicatorDefaults.backgroundColor,
) {
Box(
contentAlignment = Alignment.Center,
@@ -46,11 +43,11 @@ fun ExpandCollapseIndicator(
modifier
.size(ExpandCollapseIndicatorDimensions.size)
.clip(ExpandCollapseIndicatorDimensions.cornerShape)
.background(backgroundColor),
.background(WidgetPickerTheme.colors.expandCollapseIndicatorBackground),
) {
Icon(
modifier = Modifier.size(ExpandCollapseIndicatorDimensions.iconSize),
tint = iconColor,
tint = WidgetPickerTheme.colors.expandCollapseIndicatorIcon,
contentDescription = null, // Decorative
imageVector =
if (expanded) {
@@ -67,11 +64,3 @@ private object ExpandCollapseIndicatorDimensions {
val size = 24.dp
val iconSize = 16.dp
}
private object ExpandCollapseIndicatorDefaults {
val iconColor
@Composable get() = MaterialTheme.colorScheme.onSecondaryContainer
val backgroundColor
@Composable get() = MaterialTheme.colorScheme.secondaryContainer
}
@@ -31,17 +31,15 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.minimumInteractiveComponentSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import com.android.launcher3.widgetpicker.ui.theme.WidgetPickerTheme
/**
* A tab (suitable for displaying in a horizontal toolbar) that shows a leading icon along with its
@@ -55,17 +53,14 @@ fun LeadingIconToolbarTab(
label: String,
selected: Boolean,
onClick: () -> Unit,
selectedBackgroundColor: Color = LeadingIconToolbarTabDefaults.selectedBackgroundColor,
contentColor: Color = LeadingIconToolbarTabDefaults.contentColor,
textStyle: TextStyle = LeadingIconToolbarTabDefaults.textStyle,
iconEnterTransition: EnterTransition = LeadingIconToolbarTabDefaults.iconEnterTransition,
iconExitTransition: ExitTransition = LeadingIconToolbarTabDefaults.iconExitTransition,
) {
val backgroundColor =
if (selected) {
selectedBackgroundColor
WidgetPickerTheme.colors.toolbarTabSelectedBackground
} else {
Color.Transparent
WidgetPickerTheme.colors.toolbarTabUnSelectedBackground
}
Row(
@@ -92,24 +87,19 @@ fun LeadingIconToolbarTab(
imageVector = leadingIcon,
contentDescription = null, // decorative
modifier = Modifier.padding(end = LeadingIconToolbarTabDefaults.contentSpacing),
tint = contentColor,
tint = WidgetPickerTheme.colors.toolbarTabContent,
)
}
Text(text = label, style = textStyle, color = contentColor)
Text(
text = label,
style = WidgetPickerTheme.typography.toolbarTabLabel,
color = WidgetPickerTheme.colors.toolbarTabContent,
)
}
}
/** Holds default values used by the [LeadingIconToolbarTab]. */
object LeadingIconToolbarTabDefaults {
val selectedBackgroundColor: Color
@Composable get() = MaterialTheme.colorScheme.secondaryContainer
val contentColor: Color
@Composable get() = MaterialTheme.colorScheme.onSecondaryContainer
val textStyle: TextStyle
@Composable get() = MaterialTheme.typography.labelLarge
val horizontalPadding = 16.dp
val contentSpacing = 8.dp
@@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@@ -32,7 +31,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Measurable
@@ -42,6 +40,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastFold
import androidx.compose.ui.util.fastForEachIndexed
import androidx.compose.ui.util.fastMap
import com.android.launcher3.widgetpicker.ui.theme.WidgetPickerTheme
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@@ -70,7 +69,6 @@ import kotlinx.coroutines.launch
* length, the padding appears on both sides.
* @param maxWidth if the toolbar needs to be constraint to a specific width.
* @param minTabWidth minimum width to be guaranteed for individual tabs
* @param containerColor color to be applied to the surface of toolbar
* @param shadowElevation The size of the shadow below the surface.
*/
@Composable
@@ -82,7 +80,6 @@ fun ScrollableFloatingToolbar(
edgePadding: Dp = ScrollableFloatingToolbarDefaults.edgePadding,
maxWidth: Dp = ScrollableFloatingToolbarDefaults.maxWidth,
minTabWidth: Dp = ScrollableFloatingToolbarDefaults.minTabWidth,
containerColor: Color = ScrollableFloatingToolbarDefaults.containerColor,
shadowElevation: Dp = ScrollableFloatingToolbarDefaults.shadowElevation,
) {
check(tabs.size in 2..3) { "Unexpected number of tabs: ${tabs.size}. Suitable for 2-3 tabs." }
@@ -90,7 +87,7 @@ fun ScrollableFloatingToolbar(
val scrollState = rememberScrollState()
Surface(
color = containerColor,
color = WidgetPickerTheme.colors.toolbarBackground,
shadowElevation = shadowElevation,
shape = shape,
modifier = modifier.wrapContentSize(align = Alignment.Center),
@@ -240,7 +237,4 @@ object ScrollableFloatingToolbarDefaults {
val minTabWidth: Dp = 90.dp
val shadowElevation: Dp = 3.dp
val containerColor: Color
@Composable get() = MaterialTheme.colorScheme.surfaceBright
}
@@ -49,6 +49,7 @@ import com.android.launcher3.widgetpicker.ui.components.DragHandleDimens.dragHan
import com.android.launcher3.widgetpicker.ui.components.TitledBottomSheetDimens.headerBottomMargin
import com.android.launcher3.widgetpicker.ui.components.TitledBottomSheetDimens.sheetInnerHorizontalPadding
import com.android.launcher3.widgetpicker.ui.components.TitledBottomSheetDimens.sheetInnerTopPadding
import com.android.launcher3.widgetpicker.ui.theme.WidgetPickerTheme
import com.android.launcher3.widgetpicker.ui.windowsizeclass.WindowInfo
import com.android.launcher3.widgetpicker.ui.windowsizeclass.calculateWindowInfo
import com.android.launcher3.widgetpicker.ui.windowsizeclass.isExtraTall
@@ -104,7 +105,7 @@ fun TitledBottomSheet(
sheetState = modalBottomSheetState,
sheetGesturesEnabled = false,
sheetMaxWidth = Dp.Unspecified,
containerColor = MaterialTheme.colorScheme.surfaceContainer,
containerColor = WidgetPickerTheme.colors.sheetBackground,
onDismissRequest = onDismissRequest,
dragHandle = dragHandle,
modifier = modifier.windowInsetsPadding(WindowInsets.statusBars),
@@ -141,8 +142,8 @@ private fun Header(title: String, description: String?) {
maxLines = 1,
text = title,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.headlineSmallEmphasized,
color = MaterialTheme.colorScheme.onSurface,
style = WidgetPickerTheme.typography.sheetTitle,
color = WidgetPickerTheme.colors.sheetTitle,
)
description?.let {
Text(
@@ -150,8 +151,8 @@ private fun Header(title: String, description: String?) {
maxLines = 2,
text = it,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
style = WidgetPickerTheme.typography.sheetDescription,
color = WidgetPickerTheme.colors.sheetDescription,
)
}
}
@@ -27,13 +27,13 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.semantics.isTraversalGroup
import androidx.compose.ui.semantics.paneTitle
import androidx.compose.ui.semantics.semantics
@@ -43,6 +43,7 @@ import com.android.launcher3.widgetpicker.ui.components.TwoPaneLayoutDimensions.
import com.android.launcher3.widgetpicker.ui.components.TwoPaneLayoutDimensions.horizontalPadding
import com.android.launcher3.widgetpicker.ui.components.TwoPaneLayoutDimensions.paneSpacing
import com.android.launcher3.widgetpicker.ui.components.TwoPaneLayoutDimensions.searchBarBottomMargin
import com.android.launcher3.widgetpicker.ui.theme.WidgetPickerTheme
/**
* A layout that splits the widget picker content into two panes where the left pane takes about
@@ -58,7 +59,6 @@ import com.android.launcher3.widgetpicker.ui.components.TwoPaneLayoutDimensions.
* pane guides the user that content for selected option is now visible on right. When using
* accessibility services like talkback, after selecting an option on left, the users can use four
* finger swipe down to move focus to the right pane.
* @param rightPaneBackgroundColor color to use for that background of content on right.
*/
@Composable
fun TwoPaneLayout(
@@ -66,7 +66,6 @@ fun TwoPaneLayout(
leftContent: @Composable () -> Unit,
rightContent: @Composable () -> Unit,
rightPaneTitle: String?,
rightPaneBackgroundColor: Color = TwoPaneLayoutDefaults.rightPaneBackgroundColor,
) {
val rightPaneModifier =
if (rightPaneTitle != null) {
@@ -95,7 +94,8 @@ fun TwoPaneLayout(
.fillMaxHeight()
.weight(RIGHT_PANE_WEIGHT)
.clip(TwoPaneLayoutDimensions.rightPaneShape)
.background(rightPaneBackgroundColor),
.background(WidgetPickerTheme.colors.widgetsContainerBackground)
.verticalScroll(rememberScrollState()),
) {
rightContent()
}
@@ -118,8 +118,3 @@ private object TwoPaneLayoutDimensions {
val rightPaneShape = RoundedCornerShape(28.dp)
}
private object TwoPaneLayoutDefaults {
val rightPaneBackgroundColor
@Composable get() = MaterialTheme.colorScheme.surfaceBright
}
@@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -38,6 +37,7 @@ import androidx.compose.ui.unit.dp
import com.android.launcher3.widgetpicker.shared.model.AppIcon
import com.android.launcher3.widgetpicker.shared.model.AppIconBadge
import com.android.launcher3.widgetpicker.shared.model.WidgetAppIcon
import com.android.launcher3.widgetpicker.ui.theme.WidgetPickerTheme
/** An app icon rendered from the provided [WidgetAppIcon] with an option badge. */
@Composable
@@ -91,7 +91,7 @@ private fun PlaceholderAppIcon(size: AppIconSize) {
modifier =
Modifier.size(size.iconSize)
.background(
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.2f),
color = WidgetPickerTheme.colors.placeholderAppIcon.copy(alpha = 0.2f),
shape = CircleShape,
)
)
@@ -22,7 +22,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
@@ -139,17 +138,7 @@ private fun ExpandableWidgetAppHeader(
widgetSizeGroups = widgetApp.widgetSizeGroups,
showAllWidgetDetails = true,
previews = widgetPreviews,
modifier =
Modifier
.fillMaxWidth()
.background(
color = MaterialTheme.colorScheme.surfaceBright,
shape =
when {
isLast -> WidgetAppsListDimensions.bottomLargeShape
else -> WidgetAppsListDimensions.smallShape
},
),
modifier = Modifier.fillMaxWidth(),
onWidgetInteraction = onWidgetInteraction,
showDragShadow = showDragShadow,
)
@@ -32,24 +32,20 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Star
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.minimumInteractiveComponentSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.selected
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.android.launcher3.widgetpicker.R
import com.android.launcher3.widgetpicker.ui.theme.WidgetPickerTheme
/**
* A list header in widget picker that when [expanded] displays the [expandedContent].
@@ -79,12 +75,11 @@ fun ExpandableListHeader(
val finalModifier =
modifier
.clip(shape = shape)
.background(color = ExpandedListHeaderDefaults.backgroundColor)
.background(color = WidgetPickerTheme.colors.expandableListItemsBackground)
Column(modifier = finalModifier) {
WidgetAppHeader(
modifier = Modifier
.clickable { onClick() },
modifier = Modifier.clickable { onClick() },
leadingIcon = { leadingAppIcon() },
title = title,
subTitle = subTitle,
@@ -115,8 +110,6 @@ fun ExpandableListHeader(
* @param subTitle a short 1 line description (e.g. number of widgets in the selected app).
* @param onSelect action to perform when user clicks to select the header
* @param shape shape for the header e.g. depending on position in the list, a different corner
* @param selectedBackgroundColor background color when header is [selected]
* @param unSelectedBackgroundColor background color when header is not [selected]
*/
@Composable
fun SelectableListHeader(
@@ -127,8 +120,6 @@ fun SelectableListHeader(
subTitle: String,
onSelect: () -> Unit,
shape: RoundedCornerShape,
selectedBackgroundColor: Color = ClickableListHeaderDefaults.selectedBackgroundColor,
unSelectedBackgroundColor: Color = ClickableListHeaderDefaults.unSelectedBackgroundColor,
) {
val clickModifier =
if (!selected) {
@@ -145,9 +136,9 @@ fun SelectableListHeader(
.background(
color =
if (selected) {
selectedBackgroundColor
WidgetPickerTheme.colors.selectedListHeaderBackground
} else {
unSelectedBackgroundColor
WidgetPickerTheme.colors.unselectedListHeaderBackground
}
)
.then(clickModifier),
@@ -166,8 +157,6 @@ fun SelectableListHeader(
* @param count number of suggested widgets.
* @param onSelect action to perform when user selects the header.
* @param shape shape for the header e.g. depending on position in the list, a different corner.
* @param selectedBackgroundColor background color when header is [selected].
* @param unSelectedBackgroundColor background color when header is not [selected].
*/
@Composable
fun SelectableSuggestionsHeader(
@@ -176,25 +165,24 @@ fun SelectableSuggestionsHeader(
count: Int,
onSelect: () -> Unit,
shape: RoundedCornerShape,
selectedBackgroundColor: Color = ClickableListHeaderDefaults.selectedBackgroundColor,
unSelectedBackgroundColor: Color = ClickableListHeaderDefaults.unSelectedBackgroundColor,
) {
SelectableListHeader(
modifier = modifier,
selected = selected,
shape = shape,
selectedBackgroundColor = selectedBackgroundColor,
unSelectedBackgroundColor = unSelectedBackgroundColor,
title = stringResource(R.string.featured_widgets_tab_label),
subTitle = widgetsCountString(count),
leadingAppIcon = {
Icon(
imageVector = Icons.Filled.Star,
contentDescription = null,
tint = WidgetPickerTheme.colors.featuredHeaderLeadingIcon,
modifier =
Modifier
.clip(shape)
.background(MaterialTheme.colorScheme.surfaceBright)
.background(
WidgetPickerTheme.colors.featuredHeaderLeadingIconBackground
)
.minimumInteractiveComponentSize(),
)
},
@@ -243,24 +231,24 @@ private fun CenterText(title: String, subTitle: String, selected: Boolean, modif
text = title,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = WidgetAppListHeaderDefaults.titleTextColor,
color = WidgetPickerTheme.colors.listHeaderTitle,
style =
if (selected) {
WidgetAppListHeaderDefaults.selectedTitleTextStyle
WidgetPickerTheme.typography.selectedListHeaderTitle
} else {
WidgetAppListHeaderDefaults.unSelectedTitleTextStyle
WidgetPickerTheme.typography.unSelectedListHeaderTitle
},
)
Text(
text = subTitle,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = WidgetAppListHeaderDefaults.subTitleTextColor,
color = WidgetPickerTheme.colors.listHeaderSubTitle,
style =
if (selected) {
WidgetAppListHeaderDefaults.selectedSubTitleTextStyle
WidgetPickerTheme.typography.selectedListHeaderSubTitle
} else {
WidgetAppListHeaderDefaults.unSelectedSubTitleTextStyle
WidgetPickerTheme.typography.unSelectedListHeaderSubTitle
},
)
}
@@ -273,40 +261,6 @@ private object ListHeaderDimensions {
}
private object ExpandedListHeaderDefaults {
val backgroundColor: Color
@Composable get() = MaterialTheme.colorScheme.surfaceBright
val contentExpandAnimationSpec = fadeIn(tween(durationMillis = 500)) + expandVertically()
val contentCollapseAnimationSpec = fadeOut(tween(durationMillis = 500)) + shrinkVertically()
}
private object ClickableListHeaderDefaults {
val selectedBackgroundColor
@Composable get() = MaterialTheme.colorScheme.secondaryContainer
val unSelectedBackgroundColor
@Composable get() = Color.Transparent
}
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
private object WidgetAppListHeaderDefaults {
val selectedTitleTextStyle: TextStyle
@Composable
get() = MaterialTheme.typography.titleMediumEmphasized.copy(fontWeight = FontWeight.Medium)
val unSelectedTitleTextStyle: TextStyle
@Composable
get() = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Normal)
val selectedSubTitleTextStyle: TextStyle
@Composable get() = MaterialTheme.typography.titleSmall.copy(fontWeight = FontWeight.Medium)
val unSelectedSubTitleTextStyle: TextStyle
@Composable get() = MaterialTheme.typography.titleSmall.copy(fontWeight = FontWeight.Normal)
val titleTextColor: Color
@Composable get() = MaterialTheme.colorScheme.onSurface
val subTitleTextColor: Color
@Composable get() = MaterialTheme.colorScheme.onSurfaceVariant
}
@@ -39,7 +39,6 @@ import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.minimumInteractiveComponentSize
import androidx.compose.runtime.Composable
@@ -54,7 +53,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
@@ -66,6 +64,7 @@ import com.android.launcher3.widgetpicker.ui.WidgetInteractionInfo
import com.android.launcher3.widgetpicker.ui.components.AddButtonDefaults.TOGGLE_ANIMATION_DURATION
import com.android.launcher3.widgetpicker.ui.components.WidgetDetailsDimensions.INVISIBLE_ALPHA
import com.android.launcher3.widgetpicker.ui.components.WidgetDetailsDimensions.VISIBLE_ALPHA
import com.android.launcher3.widgetpicker.ui.theme.WidgetPickerTheme
/**
* Displays the details of the widget that can be shown below their previews.
@@ -185,7 +184,10 @@ private fun AddButton(
Button(
modifier = Modifier.minimumInteractiveComponentSize(),
contentPadding = AddButtonDimensions.paddingValues,
colors = AddButtonDefaults.colors,
colors = ButtonDefaults.buttonColors(
containerColor = WidgetPickerTheme.colors.addButtonBackground,
contentColor = WidgetPickerTheme.colors.addButtonContent
),
onClick = onClick,
) {
Icon(
@@ -222,11 +224,8 @@ private fun WidgetLabel(label: String, appIcon: (@Composable () -> Unit)?, modif
overflow = TextOverflow.Ellipsis,
maxLines = 1,
textAlign = TextAlign.Center,
style =
MaterialTheme.typography.bodyMedium.copy(
color = MaterialTheme.colorScheme.onSurface,
fontWeight = FontWeight.Medium,
),
color = WidgetPickerTheme.colors.widgetLabel,
style = WidgetPickerTheme.typography.widgetLabel,
)
}
}
@@ -242,11 +241,8 @@ private fun WidgetDescription(description: CharSequence) {
overflow = TextOverflow.Ellipsis,
textAlign = TextAlign.Center,
maxLines = 3,
style =
MaterialTheme.typography.bodySmall.copy(
color = MaterialTheme.colorScheme.onSurfaceVariant,
fontWeight = FontWeight.Normal,
),
color = WidgetPickerTheme.colors.widgetDescription,
style = WidgetPickerTheme.typography.widgetDescription,
)
}
@@ -260,11 +256,8 @@ private fun WidgetSpanSizeLabel(spanX: Int, spanY: Int) {
text = stringResource(R.string.widget_span_dimensions_format, spanX, spanY),
textAlign = TextAlign.Center,
maxLines = 1,
style =
MaterialTheme.typography.bodyMedium.copy(
color = MaterialTheme.colorScheme.onSurfaceVariant,
fontWeight = FontWeight.Normal,
),
color = WidgetPickerTheme.colors.widgetSpanText,
style = WidgetPickerTheme.typography.widgetSpanText,
modifier = Modifier.semantics { this.contentDescription = contentDescription },
)
}
@@ -291,10 +284,4 @@ private object AddButtonDefaults {
const val TOGGLE_ANIMATION_DURATION = 400
val enterTransition = fadeIn(animationSpec = tween(TOGGLE_ANIMATION_DURATION))
val exitTransition = fadeOut(animationSpec = tween(TOGGLE_ANIMATION_DURATION))
val colors: ButtonColors
@Composable get() = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
contentColor = MaterialTheme.colorScheme.onPrimary
)
}
@@ -34,7 +34,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
@@ -67,6 +66,7 @@ import com.android.launcher3.widgetpicker.shared.model.WidgetId
import com.android.launcher3.widgetpicker.shared.model.WidgetPreview
import com.android.launcher3.widgetpicker.shared.model.WidgetSizeInfo
import com.android.launcher3.widgetpicker.ui.WidgetInteractionInfo
import com.android.launcher3.widgetpicker.ui.theme.WidgetPickerTheme
import kotlin.math.roundToInt
/** Renders a different types of preview for an appwidget. */
@@ -149,11 +149,11 @@ private fun PlaceholderWidgetPreview(size: DpSize, widgetRadius: Dp) {
.width(size.width)
.height(size.height)
.background(
color = MaterialTheme.colorScheme.secondaryContainer,
color = WidgetPickerTheme.colors.widgetPlaceholderBackground,
shape = RoundedCornerShape(widgetRadius),
),
) {
CircularProgressIndicator()
CircularProgressIndicator(color = WidgetPickerTheme.colors.widgetPlaceholderContent)
}
}
@@ -37,9 +37,7 @@ import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldColors
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.minimumInteractiveComponentSize
import androidx.compose.runtime.Composable
@@ -55,14 +53,12 @@ import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.android.launcher3.widgetpicker.R
import com.android.launcher3.widgetpicker.ui.theme.WidgetPickerTheme
import kotlin.coroutines.cancellation.CancellationException
import kotlinx.coroutines.flow.Flow
@@ -114,14 +110,17 @@ fun WidgetsSearchBar(
value = text,
onValueChange = { onSearch(it) },
singleLine = true,
cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
cursorBrush = SolidColor(WidgetPickerTheme.colors.searchBarCursor),
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
keyboardActions = KeyboardActions(onSearch = {
keyboardController?.hide()
onSearch(text)
}),
interactionSource = interactionSource,
textStyle = WidgetsSearchBarDefaults.textStyle,
textStyle =
WidgetPickerTheme.typography.searchBarText.copy(
color = WidgetPickerTheme.colors.searchBarText
),
decorationBox =
@Composable { innerTextField ->
WidgetsSearchBarContent(
@@ -172,7 +171,11 @@ private fun WidgetsSearchBarContent(
isError = false,
interactionSource = interactionSource,
shape = CircleShape,
colors = WidgetsSearchBarDefaults.containerColors,
colors =
TextFieldDefaults.colors(
focusedContainerColor = WidgetPickerTheme.colors.searchBarBackground,
unfocusedContainerColor = WidgetPickerTheme.colors.searchBarBackground,
),
focusedIndicatorLineThickness = 0.dp,
unfocusedIndicatorLineThickness = 0.dp,
)
@@ -210,13 +213,22 @@ private fun LeadingButton(isSearching: Boolean, onBack: () -> Unit) {
private fun SearchIcon() {
Icon(
imageVector = Icons.Filled.Search,
tint = WidgetPickerTheme.colors.searchBarSearchIcon,
contentDescription = null, // decorative
)
}
@Composable
private fun BackButton(onClick: () -> Unit) {
IconButton(colors = WidgetsSearchBarDefaults.iconButtonColors, onClick = onClick) {
IconButton(
colors =
IconButtonDefaults.iconButtonColors()
.copy(
containerColor = Color.Transparent,
contentColor = WidgetPickerTheme.colors.searchBarBackButtonIcon,
),
onClick = onClick,
) {
Icon(
imageVector = Icons.AutoMirrored.Outlined.ArrowBack,
contentDescription = stringResource(R.string.widget_search_bar_back_button_label),
@@ -230,14 +242,22 @@ private fun PlaceholderText() {
text = stringResource(R.string.widgets_search_bar_hint),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = WidgetsSearchBarDefaults.placeholderTextColor,
style = WidgetsSearchBarDefaults.placeholderTextStyle,
color = WidgetPickerTheme.colors.searchBarPlaceholderText,
style = WidgetPickerTheme.typography.searchBarPlaceholderText,
)
}
@Composable
private fun ClearButton(onClick: () -> Unit) {
IconButton(colors = WidgetsSearchBarDefaults.iconButtonColors, onClick = onClick) {
IconButton(
colors =
IconButtonDefaults.iconButtonColors()
.copy(
containerColor = Color.Transparent,
contentColor = WidgetPickerTheme.colors.searchBarClearButtonIcon,
),
onClick = onClick,
) {
Icon(
imageVector = Icons.Filled.Close,
contentDescription = stringResource(R.string.widget_search_bar_clear_button_label),
@@ -249,37 +269,3 @@ private object WidgetsSearchBarDimens {
val paddingValues = PaddingValues(horizontal = 16.dp, vertical = 8.dp)
val minHeight = 52.dp
}
private object WidgetsSearchBarDefaults {
val containerColors: TextFieldColors
@Composable
get() =
TextFieldDefaults.colors(
focusedContainerColor = MaterialTheme.colorScheme.surfaceBright,
unfocusedContainerColor = MaterialTheme.colorScheme.surfaceBright,
)
val placeholderTextColor: Color
@Composable get() = MaterialTheme.colorScheme.onSurfaceVariant
val iconButtonColors
@Composable
get() = IconButtonDefaults.iconButtonColors().copy(containerColor = Color.Transparent)
val textStyle: TextStyle
@Composable
get() =
MaterialTheme.typography.bodyLarge.copy(
fontSize = 20.sp,
fontWeight = FontWeight.Normal,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
val placeholderTextStyle: TextStyle
@Composable
get() =
MaterialTheme.typography.bodyLarge.copy(
fontSize = 20.sp,
fontWeight = FontWeight.Normal,
)
}
@@ -16,11 +16,10 @@
package com.android.launcher3.widgetpicker.ui.fullcatalog.screens.landing
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
@@ -28,6 +27,7 @@ import com.android.launcher3.widgetpicker.shared.model.WidgetAppId
import com.android.launcher3.widgetpicker.ui.WidgetInteractionInfo
import com.android.launcher3.widgetpicker.ui.components.WidgetsGrid
import com.android.launcher3.widgetpicker.ui.components.WidgetsSearchBar
import com.android.launcher3.widgetpicker.ui.theme.WidgetPickerTheme
/**
* View displayed when user opens the full catalog of widgets in widget picker.
@@ -106,10 +106,10 @@ private fun LandingScreen(
) {
val featuredWidgetsContent: @Composable () -> Unit = {
WidgetsGrid(
modifier = Modifier
.fillMaxSize()
.wrapContentSize()
.verticalScroll(rememberScrollState()),
modifier =
Modifier
.fillMaxSize()
.wrapContentSize(),
widgetSizeGroups = featuredWidgetsState.sizeGroups,
showAllWidgetDetails = false,
previews = featuredWidgetPreviewsState.previews,
@@ -24,13 +24,14 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.List
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.Star
import androidx.compose.material.icons.outlined.Work
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@@ -60,6 +61,7 @@ import com.android.launcher3.widgetpicker.ui.fullcatalog.screens.landing.Landing
import com.android.launcher3.widgetpicker.ui.fullcatalog.screens.landing.LandingScreenSinglePaneDimens.bottomTabsTopPadding
import com.android.launcher3.widgetpicker.ui.fullcatalog.screens.landing.LandingScreenSinglePaneDimens.contentShape
import com.android.launcher3.widgetpicker.ui.fullcatalog.screens.landing.LandingScreenSinglePaneDimens.pagerItemsSpacing
import com.android.launcher3.widgetpicker.ui.theme.WidgetPickerTheme
import kotlinx.coroutines.launch
/**
@@ -115,10 +117,12 @@ fun LandingScreenSinglePane(
when (pageIndex) {
FEATURED_TAB_INDEX -> {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.fillMaxSize()
.clip(contentShape)
.background(MaterialTheme.colorScheme.surfaceBright)
.background(WidgetPickerTheme.colors.widgetsContainerBackground)
.verticalScroll(rememberScrollState())
) {
featuredWidgetsContent()
}
@@ -25,9 +25,7 @@ import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.outlined.Work
@@ -149,7 +147,6 @@ fun LandingScreenTwoPane(
browseWidgetsState = browseWidgetsState,
selectedPersonalWidgetAppId = selectedPersonalWidgetAppId,
personalWidgetPreviewsState = personalWidgetPreviewsState,
widgetAppIconsState = widgetAppIconsState,
selectedWorkWidgetAppId = selectedWorkWidgetAppId,
workWidgetPreviewsState = workWidgetPreviewsState,
onWidgetInteraction = onWidgetInteraction,
@@ -207,7 +204,6 @@ private fun RightPaneContent(
browseWidgetsState: BrowseWidgetsState.Data,
selectedPersonalWidgetAppId: WidgetAppId?,
personalWidgetPreviewsState: PreviewsState,
widgetAppIconsState: AppIconsState,
selectedWorkWidgetAppId: WidgetAppId?,
workWidgetPreviewsState: PreviewsState,
onWidgetInteraction: (WidgetInteractionInfo) -> Unit,
@@ -230,12 +226,10 @@ private fun RightPaneContent(
WidgetsGrid(
modifier = Modifier
.fillMaxWidth()
.wrapContentSize()
.verticalScroll(rememberScrollState()),
.wrapContentSize(),
showAllWidgetDetails = true,
widgetSizeGroups = selectedPersonalWidgets,
previews = personalWidgetPreviewsState.previews,
appIcons = widgetAppIconsState.icons,
onWidgetInteraction = onWidgetInteraction,
showDragShadow = showDragShadow,
)
@@ -256,12 +250,10 @@ private fun RightPaneContent(
WidgetsGrid(
modifier = Modifier
.fillMaxWidth()
.wrapContentSize()
.verticalScroll(rememberScrollState()),
.wrapContentSize(),
showAllWidgetDetails = true,
widgetSizeGroups = selectedWorkWidgets,
previews = workWidgetPreviewsState.previews,
appIcons = widgetAppIconsState.icons,
onWidgetInteraction = onWidgetInteraction,
showDragShadow = showDragShadow,
)
@@ -20,8 +20,6 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
@@ -200,12 +198,10 @@ fun SearchScreenTwoPane(
WidgetsGrid(
modifier = Modifier
.fillMaxWidth()
.wrapContentSize()
.verticalScroll(rememberScrollState()),
.wrapContentSize(),
showAllWidgetDetails = true,
widgetSizeGroups = selectedWidgets,
previews = widgetPreviewsState.previews,
appIcons = appIconsState.icons,
onWidgetInteraction = onWidgetInteraction,
showDragShadow = showDragShadow,
)