diff --git a/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Icon.kt b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Icon.kt new file mode 100644 index 0000000..da64984 --- /dev/null +++ b/flexiui-core/src/commonMain/kotlin/com/highcapable/flexiui/component/Icon.kt @@ -0,0 +1,95 @@ +/* + * Flexi UI - A flexible and useful UI component library. + * Copyright (C) 2019-2023 HighCapable + * https://github.com/BetterAndroid/FlexiUI + * + * Apache License Version 2.0 + * + * 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 + * + * https://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. + * + * This file is created by fankes on 2023/11/10. + */ +@file:Suppress("unused") + +package com.highcapable.flexiui.component + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.paint +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.toolingGraphicsLayer +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.rememberVectorPainter +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.role +import androidx.compose.ui.semantics.semantics +import com.highcapable.flexiui.LocalSizes + +@Composable +fun Icon( + imageVector: ImageVector, + contentDescription: String? = null, + modifier: Modifier = Modifier, + tint: Color = Color.Unspecified +) { + val painter = rememberVectorPainter(imageVector) + Icon(painter, contentDescription, modifier, tint) +} + +@Composable +fun Icon( + painter: Painter, + contentDescription: String? = null, + modifier: Modifier = Modifier, + tint: Color = Color.Unspecified +) { + // TODO: b/149735981 semantics for content description + val colorFilter = if (tint == Color.Unspecified) null else ColorFilter.tint(tint) + val semantics = if (contentDescription != null) + Modifier.semantics { + this.contentDescription = contentDescription + this.role = Role.Image + } + else Modifier + Box( + modifier = modifier.toolingGraphicsLayer() + .defaultSizeFor(painter) + .paint( + painter, + colorFilter = colorFilter, + contentScale = ContentScale.Fit + ) + .then(semantics) + ) +} + +@Composable +private fun Modifier.defaultSizeFor(painter: Painter) = then( + if (painter.intrinsicSize == Size.Unspecified || painter.intrinsicSize.isInfinite()) + Modifier.size(defaultIconSize()) + else Modifier +) + +@Composable +@ReadOnlyComposable +private fun defaultIconSize() = LocalSizes.current.iconSizeSecondary + +private fun Size.isInfinite() = width.isInfinite() && height.isInfinite() \ No newline at end of file