Add tooltips to widgets (#1229)

* add tooltips

* update toolbar tooltip

* prettify ifelse statements
This commit is contained in:
leekleak 2025-01-18 17:17:23 +02:00 committed by GitHub
parent 11ae8386fd
commit 8d7084e23f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 208 additions and 272 deletions

View File

@ -1,7 +1,6 @@
package de.mm20.launcher2.ui.component
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
@ -16,16 +15,11 @@ import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Text
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
@ -35,7 +29,6 @@ import androidx.compose.ui.unit.dp
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.ktx.toDp
import de.mm20.launcher2.ui.locals.LocalWindowPosition
import kotlinx.coroutines.launch
import kotlin.math.min
@Composable
@ -57,7 +50,6 @@ fun Toolbar(
@Composable
fun Icons(actions: List<ToolbarAction>, slots: Int) {
val scope = rememberCoroutineScope()
for (i in 0 until min(slots, actions.size)) {
if (i == slots - 1 && slots != actions.size) {
var showMenu by remember { mutableStateOf(false) }
@ -82,28 +74,11 @@ fun Icons(actions: List<ToolbarAction>, slots: Int) {
}
} else {
val action = actions[i]
val tooltipState = rememberTooltipState()
TooltipBox(
positionProvider = TooltipDefaults.rememberTooltipPositionProvider(),
tooltip = {
PlainTooltip {
Text(action.label)
}
},
state = tooltipState
) {
Tooltip(action.label) {
when (action) {
is DefaultToolbarAction -> {
IconButton(
onClick = action.action,
modifier = Modifier.combinedClickable(
onClick = {},
onLongClick = {
scope.launch {
tooltipState.show()
}
}
)
) {
Icon(action.icon, contentDescription = action.label)
}
@ -116,14 +91,6 @@ fun Icons(actions: List<ToolbarAction>, slots: Int) {
onClick = {
showMenu = true
},
modifier = Modifier.combinedClickable(
onClick = {},
onLongClick = {
scope.launch {
tooltipState.show()
}
}
)
) {
Icon(action.icon, contentDescription = action.label)
}

View File

@ -0,0 +1,28 @@
package de.mm20.launcher2.ui.component
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Text
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@Composable
fun Tooltip (
tooltipText: String,
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
val tooltipState = rememberTooltipState()
TooltipBox(
state = tooltipState,
positionProvider = TooltipDefaults.rememberTooltipPositionProvider(),
tooltip = { PlainTooltip { Text(tooltipText) } },
modifier = modifier
) {
content()
}
}

View File

@ -49,23 +49,17 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Slider
import androidx.compose.material3.SliderDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
@ -88,13 +82,13 @@ import de.mm20.launcher2.music.PlaybackState
import de.mm20.launcher2.music.SupportedActions
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.MissingPermissionBanner
import de.mm20.launcher2.ui.component.Tooltip
import de.mm20.launcher2.ui.ktx.conditional
import de.mm20.launcher2.ui.launcher.transitions.EnterHomeTransitionParams
import de.mm20.launcher2.ui.launcher.transitions.HandleEnterHomeTransition
import de.mm20.launcher2.ui.locals.LocalCardStyle
import de.mm20.launcher2.ui.locals.LocalWindowSize
import de.mm20.launcher2.widgets.MusicWidget
import kotlinx.coroutines.launch
import kotlin.math.min
@Composable
@ -334,44 +328,58 @@ fun MusicWidget(widget: MusicWidget) {
) {
if (supportedActions.skipToPrevious) {
IconButton(
onClick = {
viewModel.skipPrevious()
}) {
Icon(
imageVector = Icons.Rounded.SkipPrevious,
stringResource(R.string.music_widget_previous_track)
)
Tooltip(
tooltipText = stringResource(R.string.music_widget_previous_track)
) {
IconButton(
onClick = {
viewModel.skipPrevious()
}) {
Icon(
imageVector = Icons.Rounded.SkipPrevious,
stringResource(R.string.music_widget_previous_track)
)
}
}
}
val playPauseIcon =
AnimatedImageVector.animatedVectorResource(R.drawable.anim_ic_play_pause)
FilledTonalIconButton(
colors = IconButtonDefaults.filledTonalIconButtonColors(
containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = LocalCardStyle.current.opacity),
),
onClick = { viewModel.togglePause() },
) {
Icon(
painter = rememberAnimatedVectorPainter(
playPauseIcon,
atEnd = playbackState == PlaybackState.Playing
),
contentDescription = if (playbackState == PlaybackState.Playing) {
stringResource(R.string.music_widget_pause)
} else {
stringResource(R.string.music_widget_play)
}
Tooltip(
tooltipText = stringResource(
if (playbackState == PlaybackState.Playing) R.string.music_widget_pause
else R.string.music_widget_play
)
) {
FilledTonalIconButton(
colors = IconButtonDefaults.filledTonalIconButtonColors(
containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = LocalCardStyle.current.opacity),
),
onClick = { viewModel.togglePause() },
) {
Icon(
painter = rememberAnimatedVectorPainter(
playPauseIcon,
atEnd = playbackState == PlaybackState.Playing
),
contentDescription = stringResource(
if (playbackState == PlaybackState.Playing) R.string.music_widget_pause
else R.string.music_widget_play
)
)
}
}
if (supportedActions.skipToNext) {
IconButton(onClick = {
viewModel.skipNext()
}) {
Icon(
imageVector = Icons.Rounded.SkipNext,
stringResource(R.string.music_widget_next_track)
)
Tooltip(
tooltipText = stringResource(R.string.music_widget_next_track)
) {
IconButton(onClick = {
viewModel.skipNext()
}) {
Icon(
imageVector = Icons.Rounded.SkipNext,
stringResource(R.string.music_widget_next_track)
)
}
}
}
CustomActions(
@ -394,29 +402,12 @@ fun CustomActions(
val usedSlots = 1 + (if (actions.skipToPrevious) 1 else 0) + (if (actions.skipToNext) 1 else 0)
val slots = 5 - usedSlots
val scope = rememberCoroutineScope()
for (i in 0 until min(actions.customActions.size, slots - 1)) {
val action = actions.customActions[i]
val tooltipState = rememberTooltipState()
TooltipBox(
positionProvider = TooltipDefaults.rememberTooltipPositionProvider(),
state = tooltipState,
tooltip = {
PlainTooltip {
Text(action.name.toString())
}
},
Tooltip(
tooltipText = action.name.toString()
) {
IconButton(
modifier = Modifier.combinedClickable(
onClick = {},
onLongClick = {
scope.launch {
tooltipState.show()
}
}
),
onClick = {
onActionSelected(action)
}
@ -428,8 +419,12 @@ fun CustomActions(
if (slots < actions.customActions.size) {
var showOverflowMenu by remember { mutableStateOf(false) }
Box {
IconButton(onClick = { showOverflowMenu = true }) {
Icon(imageVector = Icons.Rounded.MoreVert, contentDescription = null)
Tooltip(
tooltipText = stringResource(R.string.action_more_actions)
) {
IconButton(onClick = { showOverflowMenu = true }) {
Icon(imageVector = Icons.Rounded.MoreVert, contentDescription = null)
}
}
DropdownMenu(
expanded = showOverflowMenu,
@ -456,26 +451,11 @@ fun CustomActions(
}
}
} else if (slots == actions.customActions.size) {
val tooltipState = rememberTooltipState()
val action = actions.customActions.last()
TooltipBox(
state = tooltipState,
positionProvider = TooltipDefaults.rememberTooltipPositionProvider(),
tooltip = {
PlainTooltip {
Text(action.name.toString())
}
}
Tooltip (
tooltipText = action.name.toString()
) {
IconButton(
modifier = Modifier.combinedClickable(
onClick = {},
onLongClick = {
scope.launch {
tooltipState.show()
}
}
),
onClick = {
onActionSelected(action)
}

View File

@ -43,22 +43,17 @@ import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarResult
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -74,6 +69,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.Banner
import de.mm20.launcher2.ui.component.BottomSheetDialog
import de.mm20.launcher2.ui.component.Tooltip
import de.mm20.launcher2.ui.component.markdown.MarkdownEditor
import de.mm20.launcher2.ui.component.markdown.MarkdownText
import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
@ -94,8 +90,6 @@ fun NotesWidget(
val snackbarHostState = LocalSnackbarHostState.current
val lifecycleOwner = LocalLifecycleOwner.current
val scope = rememberCoroutineScope()
var showConflictResolveSheet by remember { mutableStateOf(false) }
var readWriteErrorSheetText by remember { mutableStateOf<String?>(null) }
@ -181,20 +175,12 @@ fun NotesWidget(
Row(
modifier = Modifier.padding(8.dp),
) {
val tooltipState = rememberTooltipState()
TooltipBox(
state = tooltipState,
positionProvider = TooltipDefaults.rememberTooltipPositionProvider(),
tooltip = {
PlainTooltip {
Text(
stringResource(
if (widget.config.linkedFile == null) R.string.note_widget_link_file
else R.string.note_widget_action_unlink_file
)
)
}
}) {
Tooltip(
tooltipText = stringResource(
if (widget.config.linkedFile == null) R.string.note_widget_link_file
else R.string.note_widget_action_unlink_file
),
) {
IconButton(
onClick = {
if (widget.config.linkedFile == null) {
@ -205,14 +191,6 @@ fun NotesWidget(
viewModel.unlinkFile(context)
}
},
modifier = Modifier.combinedClickable(
onClick = {},
onLongClick = {
scope.launch {
tooltipState.show()
}
}
)
) {
Icon(
if (widget.config.linkedFile == null) Icons.Rounded.Link
@ -225,26 +203,13 @@ fun NotesWidget(
}
}
if (isLastWidget == false) {
TooltipBox(
state = tooltipState,
positionProvider = TooltipDefaults.rememberTooltipPositionProvider(),
tooltip = {
PlainTooltip {
Text(stringResource(R.string.notes_widget_action_dismiss))
}
}) {
Tooltip(
tooltipText = stringResource(R.string.notes_widget_action_dismiss)
) {
IconButton(
onClick = {
viewModel.dismissNote()
},
modifier = Modifier.combinedClickable(
onClick = {},
onLongClick = {
scope.launch {
tooltipState.show()
}
}
)
) {
Icon(Icons.Rounded.Delete, null)
}
@ -297,8 +262,12 @@ fun NotesWidget(
}
Spacer(modifier = Modifier.weight(1f))
Box {
IconButton(onClick = { showMenu = true }) {
Icon(Icons.Rounded.MoreVert, stringResource(R.string.action_more_actions))
Tooltip(
tooltipText = stringResource(R.string.action_more_actions)
) {
IconButton(onClick = { showMenu = true }) {
Icon(Icons.Rounded.MoreVert, stringResource(R.string.action_more_actions))
}
}
DropdownMenu(expanded = showMenu, onDismissRequest = { showMenu = false }) {
DropdownMenuItem(

View File

@ -67,6 +67,7 @@ import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.common.WeatherLocationSearchDialog
import de.mm20.launcher2.ui.component.Banner
import de.mm20.launcher2.ui.component.MissingPermissionBanner
import de.mm20.launcher2.ui.component.Tooltip
import de.mm20.launcher2.ui.component.weather.AnimatedWeatherIcon
import de.mm20.launcher2.ui.component.weather.WeatherIcon
import de.mm20.launcher2.ui.ktx.blendIntoViewScale
@ -231,32 +232,36 @@ fun CurrentWeather(forecast: Forecast, imperialUnits: Boolean) {
style = MaterialTheme.typography.titleMedium
)
}
Surface(
shape = MaterialTheme.shapes.extraSmall.copy(
topStart = CornerSize(0),
topEnd = CornerSize(0),
bottomEnd = CornerSize(0)
),
color = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = LocalCardStyle.current.opacity),
Tooltip(
tooltipText = stringResource(R.string.preference_weather_provider)
) {
Text(
text = "${forecast.provider} (${
formatTime(
LocalContext.current,
forecast.updateTime
)
})",
style = MaterialTheme.typography.bodySmall.copy(fontSize = 8.sp),
modifier = Modifier
.clickable(onClick = {
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse(forecast.providerUrl)
?: return@clickable
}
context.tryStartActivity(intent)
})
.padding(start = 8.dp, top = 4.dp, bottom = 4.dp, end = 12.dp)
)
Surface(
shape = MaterialTheme.shapes.extraSmall.copy(
topStart = CornerSize(0),
topEnd = CornerSize(0),
bottomEnd = CornerSize(0)
),
color = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = LocalCardStyle.current.opacity),
) {
Text(
text = "${forecast.provider} (${
formatTime(
LocalContext.current,
forecast.updateTime
)
})",
style = MaterialTheme.typography.bodySmall.copy(fontSize = 8.sp),
modifier = Modifier
.clickable(onClick = {
val intent = Intent(Intent.ACTION_VIEW).apply {
data = Uri.parse(forecast.providerUrl)
?: return@clickable
}
context.tryStartActivity(intent)
})
.padding(start = 8.dp, top = 4.dp, bottom = 4.dp, end = 12.dp)
)
}
}
}
Row(
@ -293,71 +298,84 @@ fun CurrentWeather(forecast: Forecast, imperialUnits: Boolean) {
horizontalArrangement = Arrangement.SpaceBetween
) {
if (forecast.humidity != null) {
Row(
verticalAlignment = Alignment.CenterVertically
Tooltip(
tooltipText = stringResource(R.string.weather_forecast_humidity)
) {
Icon(
imageVector = Icons.Rounded.HumidityPercentage,
modifier = Modifier.size(20.dp),
tint = MaterialTheme.colorScheme.secondary,
contentDescription = null
)
Spacer(modifier = Modifier.padding(3.dp))
Text(
text = "${forecast.humidity!!.roundToInt()} %",
style = MaterialTheme.typography.bodySmall,
)
}
}
if (forecast.windDirection != null || forecast.windSpeed != null) {
Row(
verticalAlignment = Alignment.CenterVertically
) {
if (forecast.windDirection != null) {
// windDirection is "fromDirection"; Wind (arrow) blows into opposite direction
val angle by animateFloatAsState(forecast.windDirection!!.toFloat() + 180f)
Row(
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Rounded.North,
modifier = Modifier
.rotate(angle)
.size(20.dp),
contentDescription = null,
tint = MaterialTheme.colorScheme.secondary,
)
} else {
Icon(
imageVector = Icons.Rounded.Air,
contentDescription = null,
imageVector = Icons.Rounded.HumidityPercentage,
modifier = Modifier.size(20.dp),
tint = MaterialTheme.colorScheme.secondary,
contentDescription = null
)
Spacer(modifier = Modifier.padding(3.dp))
Text(
text = "${forecast.humidity!!.roundToInt()} %",
style = MaterialTheme.typography.bodySmall,
)
}
Spacer(modifier = Modifier.padding(3.dp))
Text(
text = if (forecast.windSpeed != null) {
formatWindSpeed(imperialUnits, forecast)
}
}
if (forecast.windDirection != null || forecast.windSpeed != null) {
Tooltip(
tooltipText = stringResource(R.string.weather_forecast_wind)
) {
Row(
verticalAlignment = Alignment.CenterVertically
) {
if (forecast.windDirection != null) {
// windDirection is "fromDirection"; Wind (arrow) blows into opposite direction
val angle by animateFloatAsState(forecast.windDirection!!.toFloat() + 180f)
Icon(
imageVector = Icons.Rounded.North,
modifier = Modifier
.rotate(angle)
.size(20.dp),
contentDescription = null,
tint = MaterialTheme.colorScheme.secondary,
)
} else {
windDirectionAsWord(forecast.windDirection!!)
},
style = MaterialTheme.typography.bodySmall,
)
Icon(
imageVector = Icons.Rounded.Air,
contentDescription = null,
modifier = Modifier.size(20.dp),
tint = MaterialTheme.colorScheme.secondary,
)
}
Spacer(modifier = Modifier.padding(3.dp))
Text(
text = if (forecast.windSpeed != null) {
formatWindSpeed(imperialUnits, forecast)
} else {
windDirectionAsWord(forecast.windDirection!!)
},
style = MaterialTheme.typography.bodySmall,
)
}
}
}
if (forecast.precipitation != null) {
Row(
verticalAlignment = Alignment.CenterVertically
Tooltip(
tooltipText = stringResource(id = R.string.weather_forecast_precipitation)
) {
Icon(
imageVector = Icons.Rounded.Rain,
modifier = Modifier.size(20.dp),
contentDescription = null,
tint = MaterialTheme.colorScheme.secondary,
)
Spacer(modifier = Modifier.padding(3.dp))
Text(
text = formatPrecipitation(imperialUnits, forecast),
style = MaterialTheme.typography.bodySmall,
)
Row(
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Rounded.Rain,
modifier = Modifier.size(20.dp),
contentDescription = null,
tint = MaterialTheme.colorScheme.secondary,
)
Spacer(modifier = Modifier.padding(3.dp))
Text(
text = formatPrecipitation(imperialUnits, forecast),
style = MaterialTheme.typography.bodySmall,
)
}
}
}
}

View File

@ -16,17 +16,12 @@ import androidx.compose.material.icons.rounded.SettingsSuggest
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -36,6 +31,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.BottomSheetDialog
import de.mm20.launcher2.ui.component.Tooltip
import de.mm20.launcher2.ui.component.colorpicker.HctColorPicker
import de.mm20.launcher2.ui.component.colorpicker.rememberHctColorPickerState
import de.mm20.launcher2.ui.component.preferences.SwitchPreference
@ -51,17 +47,8 @@ fun CorePaletteColorPreference(
) {
var showDialog by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
val tooltipState = rememberTooltipState()
TooltipBox(
state = tooltipState,
positionProvider = TooltipDefaults.rememberTooltipPositionProvider(),
tooltip = {
PlainTooltip {
Text(title)
}
},
Tooltip(
tooltipText = title
) {
ColorSwatch(
color = Color(value ?: defaultValue),

View File

@ -4,7 +4,6 @@ import androidx.compose.animation.AnimatedContent
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@ -25,21 +24,16 @@ import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.SegmentedButton
import androidx.compose.material3.SegmentedButtonDefaults
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -61,11 +55,11 @@ import de.mm20.launcher2.themes.atTone
import de.mm20.launcher2.themes.get
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.BottomSheetDialog
import de.mm20.launcher2.ui.component.Tooltip
import de.mm20.launcher2.ui.component.colorpicker.HctColorPicker
import de.mm20.launcher2.ui.component.colorpicker.rememberHctColorPickerState
import de.mm20.launcher2.ui.ktx.hct
import hct.Hct
import kotlinx.coroutines.launch
import kotlin.math.roundToInt
import de.mm20.launcher2.themes.Color as ThemeColor
@ -80,25 +74,15 @@ fun ThemeColorPreference(
) {
var showDialog by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
val tooltipState = rememberTooltipState()
TooltipBox(
state = tooltipState,
positionProvider = TooltipDefaults.rememberTooltipPositionProvider(),
tooltip = { PlainTooltip { Text(title) } }
Tooltip(
tooltipText = title
) {
ColorSwatch(
color = Color((value ?: defaultValue).get(corePalette)),
modifier = modifier
.size(48.dp)
.combinedClickable(
.clickable(
onClick = { showDialog = true },
onLongClick = {
scope.launch {
tooltipState.show()
}
}
),
)
}

View File

@ -1005,4 +1005,7 @@
<item quantity="other">%1$s lists selected</item>
</plurals>
<string name="reset_icon">Reset icon</string>
<string name="weather_forecast_humidity">Humidity</string>
<string name="weather_forecast_wind">Wind</string>
<string name="weather_forecast_precipitation">Precipitation</string>
</resources>