Skip to content

Commit

Permalink
library: Add a basic Icon
Browse files Browse the repository at this point in the history
  • Loading branch information
YuKongA committed Oct 22, 2024
1 parent b2d1e0d commit 172724d
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 14 deletions.
8 changes: 3 additions & 5 deletions composeApp/src/commonMain/kotlin/MainPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import androidx.compose.ui.unit.dp
import component.OtherComponent
import component.TextComponent
import top.yukonga.miuix.kmp.basic.BasicComponent
import top.yukonga.miuix.kmp.basic.Icon
import top.yukonga.miuix.kmp.basic.InputField
import top.yukonga.miuix.kmp.basic.LazyColumn
import top.yukonga.miuix.kmp.basic.ScrollBehavior
Expand Down Expand Up @@ -66,13 +67,10 @@ fun MainPage(
onExpandedChange = { expanded = it },
label = "Search",
leadingIcon = {
Image(
Icon(
modifier = Modifier.padding(horizontal = 16.dp),
imageVector = MiuixIcons.Search,
colorFilter = BlendModeColorFilter(
MiuixTheme.colorScheme.onSurfaceContainer,
BlendMode.SrcIn
),
tint = MiuixTheme.colorScheme.onSurfaceContainer,
contentDescription = "Search"
)
},
Expand Down
5 changes: 2 additions & 3 deletions composeApp/src/commonMain/kotlin/UITest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch
import top.yukonga.miuix.kmp.basic.FloatingActionButton
import top.yukonga.miuix.kmp.basic.HorizontalPager
import top.yukonga.miuix.kmp.basic.Icon
import top.yukonga.miuix.kmp.basic.IconButton
import top.yukonga.miuix.kmp.basic.MiuixScrollBehavior
import top.yukonga.miuix.kmp.basic.NavigationBar
Expand All @@ -49,7 +50,6 @@ import top.yukonga.miuix.kmp.basic.TopAppBar
import top.yukonga.miuix.kmp.basic.rememberTopAppBarState
import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.icons.GitHub
import top.yukonga.miuix.kmp.theme.MiuixTheme
import utils.FPSMonitor

@OptIn(FlowPreview::class)
Expand Down Expand Up @@ -111,9 +111,8 @@ fun UITest(
modifier = Modifier.padding(end = 12.dp),
onClick = { }
) {
Image(
Icon(
imageVector = Icons.Rounded.Menu,
colorFilter = ColorFilter.tint(MiuixTheme.colorScheme.onBackground.copy(0.8f)),
contentDescription = "Menu"
)
}
Expand Down
8 changes: 3 additions & 5 deletions composeApp/src/commonMain/kotlin/component/TextComponent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
Expand All @@ -23,13 +22,13 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.unit.dp
import top.yukonga.miuix.kmp.basic.BasicComponent
import top.yukonga.miuix.kmp.basic.Box
import top.yukonga.miuix.kmp.basic.Button
import top.yukonga.miuix.kmp.basic.Card
import top.yukonga.miuix.kmp.basic.Checkbox
import top.yukonga.miuix.kmp.basic.Icon
import top.yukonga.miuix.kmp.basic.SmallTitle
import top.yukonga.miuix.kmp.basic.Switch
import top.yukonga.miuix.kmp.basic.Text
Expand Down Expand Up @@ -117,10 +116,9 @@ fun TextComponent() {
Box(
contentAlignment = Alignment.TopStart,
) {
Image(
colorFilter = ColorFilter.tint(MiuixTheme.colorScheme.onBackground),
Icon(
imageVector = Icons.Rounded.AccountBox,
contentDescription = "Person",
contentDescription = "Account",
)
}
},
Expand Down
132 changes: 132 additions & 0 deletions miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/Icon.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package top.yukonga.miuix.kmp.basic

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
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.ImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
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 androidx.compose.ui.unit.dp
import top.yukonga.miuix.kmp.theme.MiuixTheme

/**
* A [Icon] component that draws [imageVector] using [tint], with a default value.
*
* @param imageVector [ImageVector] to draw inside this icon
* @param contentDescription text used by accessibility services to describe what this icon
* represents. This should always be provided unless this icon is used for decorative purposes,
* and does not represent a meaningful action that a user can take. This text should be localized,
* such as by using [androidx.compose.ui.res.stringResource] or similar
* @param modifier the [Modifier] to be applied to this icon
* @param tint tint to be applied to [imageVector]. If [Color.Unspecified] is provided, then no tint
* is applied.
*/
@Composable
fun Icon(
imageVector: ImageVector,
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = MiuixTheme.colorScheme.onBackground
) {
Icon(
painter = rememberVectorPainter(imageVector),
contentDescription = contentDescription,
modifier = modifier,
tint = tint
)
}

/**
* A [Icon] component that draws [bitmap] using [tint], with a default value.
*
* @param bitmap [ImageBitmap] to draw inside this icon
* @param contentDescription text used by accessibility services to describe what this icon
* represents. This should always be provided unless this icon is used for decorative purposes,
* and does not represent a meaningful action that a user can take. This text should be localized,
* such as by using [androidx.compose.ui.res.stringResource] or similar
* @param modifier the [Modifier] to be applied to this icon
* @param tint tint to be applied to [bitmap]. If [Color.Unspecified] is provided, then no tint is
* applied.
*/
@Composable
fun Icon(
bitmap: ImageBitmap,
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = MiuixTheme.colorScheme.onBackground
) {
val painter = remember(bitmap) { BitmapPainter(bitmap) }
Icon(
painter = painter,
contentDescription = contentDescription,
modifier = modifier,
tint = tint
)
}

/**
* A [Icon] component that draws [painter] using [tint], with a default value.
*
* @param painter [Painter] to draw inside this icon
* @param contentDescription text used by accessibility services to describe what this icon
* represents. This should always be provided unless this icon is used for decorative purposes,
* and does not represent a meaningful action that a user can take. This text should be localized,
* such as by using [androidx.compose.ui.res.stringResource] or similar
* @param modifier the [Modifier] to be applied to this icon
* @param tint tint to be applied to [painter]. If [Color.Unspecified] is provided, then no tint is
* applied.
*/
@Composable
fun Icon(
painter: Painter,
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = MiuixTheme.colorScheme.onBackground
) {
val colorFilter =
remember(tint) { 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
.toolingGraphicsLayer()
.defaultSizeFor(painter)
.paint(painter, colorFilter = colorFilter, contentScale = ContentScale.Fit)
.then(semantics)
)
}

private fun Modifier.defaultSizeFor(painter: Painter) =
this.then(
if (painter.intrinsicSize == Size.Unspecified || painter.intrinsicSize.isInfinite()) {
DefaultIconSizeModifier
} else {
Modifier
}
)

private fun Size.isInfinite() = width.isInfinite() && height.isInfinite()

// Default icon size, for icons with no intrinsic size information
private val DefaultIconSizeModifier = Modifier.size(24.dp)
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import top.yukonga.miuix.kmp.utils.SmoothRoundedCornerShape
* @param backgroundColor The background color of of the [IconButton].
* @param minHeight The minimum height of of the [IconButton].
* @param minWidth The minimum width of the [IconButton].
* @param content The content of this icon button, typically an [Image].
* @param content The content of this icon button, typically an [Icon].
*/
@Composable
fun IconButton(
Expand Down

0 comments on commit 172724d

Please sign in to comment.