diff --git a/app/src/main/kotlin/dev/patrickgold/florisboard/ime/clipboard/ClipboardInputLayout.kt b/app/src/main/kotlin/dev/patrickgold/florisboard/ime/clipboard/ClipboardInputLayout.kt index d9edf96e..5e0263e2 100644 --- a/app/src/main/kotlin/dev/patrickgold/florisboard/ime/clipboard/ClipboardInputLayout.kt +++ b/app/src/main/kotlin/dev/patrickgold/florisboard/ime/clipboard/ClipboardInputLayout.kt @@ -29,7 +29,6 @@ import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.interaction.MutableInteractionSource @@ -50,7 +49,6 @@ import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan import androidx.compose.foundation.lazy.staggeredgrid.items import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState -import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack @@ -110,19 +108,18 @@ import dev.patrickgold.florisboard.lib.observeAsTransformingState import dev.patrickgold.florisboard.lib.util.NetworkUtils import dev.patrickgold.jetpref.datastore.model.observeAsState import kotlinx.coroutines.delay -import kotlinx.coroutines.runBlocking import org.florisboard.lib.android.AndroidKeyguardManager import org.florisboard.lib.android.AndroidVersion import org.florisboard.lib.android.showShortToast import org.florisboard.lib.android.systemService import org.florisboard.lib.snygg.ui.SnyggBox import org.florisboard.lib.snygg.ui.SnyggButton +import org.florisboard.lib.snygg.ui.SnyggChip import org.florisboard.lib.snygg.ui.SnyggColumn import org.florisboard.lib.snygg.ui.SnyggIcon import org.florisboard.lib.snygg.ui.SnyggIconButton import org.florisboard.lib.snygg.ui.SnyggRow import org.florisboard.lib.snygg.ui.SnyggText -import java.util.Objects private val ItemWidth = 200.dp private val DialogWidth = 240.dp @@ -404,7 +401,7 @@ fun ClipboardInputLayout( clickAndSemanticsModifier = Modifier.florisHorizontalScroll(), ) { @Composable - fun Chip( + fun FilterChip( imageVector: ImageVector, text: String, itemType: ItemType, @@ -416,45 +413,30 @@ fun ClipboardInputLayout( "type" to itemType.toString().lowercase(), ) } - SnyggRow( + SnyggChip( elementName = FlorisImeUi.ClipboardFilterChip.elementName, attributes = attributes, - clickAndSemanticsModifier = Modifier - .clickable( - interactionSource = null, - indication = ripple(), - onClick = { - if (!activeFilterTypes.add(itemType)) { - activeFilterTypes.remove(itemType) - } - }, - ), - verticalAlignment = Alignment.CenterVertically, - ) { - SnyggIcon( - elementName = FlorisImeUi.ClipboardFilterChipIcon.elementName, - attributes = attributes, - imageVector = imageVector, - ) - SnyggText( - elementName = FlorisImeUi.ClipboardFilterChipText.elementName, - attributes = attributes, - text = text, - ) - } + onClick = { + if (!activeFilterTypes.add(itemType)) { + activeFilterTypes.remove(itemType) + } + }, + imageVector = imageVector, + text = text, + ) } - Chip( + FilterChip( imageVector = Icons.Default.TextFields, text = "Text", itemType = ItemType.TEXT, ) - Chip( + FilterChip( imageVector = Icons.Default.Image, text = "Images", itemType = ItemType.IMAGE, ) - Chip( + FilterChip( imageVector = Icons.Default.Movie, text = "Videos", itemType = ItemType.VIDEO, diff --git a/lib/snygg/src/main/kotlin/org/florisboard/lib/snygg/ui/SnyggChip.kt b/lib/snygg/src/main/kotlin/org/florisboard/lib/snygg/ui/SnyggChip.kt new file mode 100644 index 00000000..6f11289b --- /dev/null +++ b/lib/snygg/src/main/kotlin/org/florisboard/lib/snygg/ui/SnyggChip.kt @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2025 The FlorisBoard Contributors + * + * 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 org.florisboard.lib.snygg.ui + +import androidx.compose.foundation.clickable +import androidx.compose.material3.ripple +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import org.florisboard.lib.snygg.SnyggQueryAttributes +import org.florisboard.lib.snygg.SnyggSelector +import org.florisboard.lib.snygg.SnyggStylesheet + +/** + * Simple layout composable that places its children in a horizontal sequence. + * + * This composable infers its style from the current [SnyggTheme][org.florisboard.lib.snygg.SnyggTheme], which is + * required to be provided by [ProvideSnyggTheme]. + * + * @param elementName The name of this element. If `null` the style will be inherited from the parent element. + * @param attributes The attributes of the element used to refine the query. + * @param selector A specific SnyggSelector to query the style for. + * @param modifier The modifier to be applied to the Row. + * @param onClick The action that is executed on click + * @param enabled Weather the chip is enabled + * @param imageVector Icon + * @param text Text + * + * @since 0.5.0-alpha01 + * + * @see [SnyggRow] + * @see [SnyggText] + * @see [SnyggIcon] + */ +@Composable +fun SnyggChip( + elementName: String? = null, + attributes: SnyggQueryAttributes = emptyMap(), + selector: SnyggSelector? = null, + modifier: Modifier = Modifier, + onClick: () -> Unit, + enabled: Boolean = true, + imageVector: ImageVector? = null, + text: String, +) { + SnyggChip( + elementName, + attributes, + selector, + modifier, + onClick, + enabled, + icon = if (imageVector == null) null else ({ + SnyggIcon( + elementName = "$elementName-icon", + attributes = attributes, + selector = selector, + imageVector = imageVector, + ) + }), + text = { + SnyggText( + elementName = "$elementName-text", + attributes = attributes, + selector = selector, + text = text, + ) + }, + ) +} + +@Composable +internal fun SnyggChip( + elementName: String? = null, + attributes: SnyggQueryAttributes = emptyMap(), + selector: SnyggSelector? = null, + modifier: Modifier = Modifier, + onClick: () -> Unit, + enabled: Boolean = true, + icon: (@Composable () -> Unit)? = null, + text: (@Composable () -> Unit)? = null, +) { + SnyggRow( + elementName = elementName, + attributes = attributes, + selector = selector, + modifier = modifier, + clickAndSemanticsModifier = Modifier + .clickable( + interactionSource = null, + indication = ripple(), + enabled = enabled, + onClick = onClick, + ), + verticalAlignment = Alignment.CenterVertically, + ) { + icon?.invoke() + text?.invoke() + } +} + +@Preview +@Composable +private fun SimpleSnyggChip() { + val stylesheet = SnyggStylesheet.v2 { + "preview-row" { + background = rgbaColor(255, 255, 255) + foreground = rgbaColor(255, 0, 0) + padding = padding(10.dp) + } + "chip" { + background = rgbaColor(255, 0, 0) + foreground = rgbaColor(255, 255, 255) + shape = roundedCornerShape(20, 20, 20, 20) + } + } + val theme = rememberSnyggTheme(stylesheet) + + ProvideSnyggTheme(theme) { + SnyggRow("preview-row") { + SnyggChip( + elementName = "chip", + onClick = {}, + text = "Hello", + ) + } + } +}