1+ package top.yukonga.miuix.kmp.basic
2+
3+ import androidx.compose.foundation.layout.Box
4+ import androidx.compose.foundation.layout.size
5+ import androidx.compose.runtime.Composable
6+ import androidx.compose.runtime.remember
7+ import androidx.compose.ui.Modifier
8+ import androidx.compose.ui.draw.paint
9+ import androidx.compose.ui.geometry.Size
10+ import androidx.compose.ui.graphics.Color
11+ import androidx.compose.ui.graphics.ColorFilter
12+ import androidx.compose.ui.graphics.ImageBitmap
13+ import androidx.compose.ui.graphics.painter.BitmapPainter
14+ import androidx.compose.ui.graphics.painter.Painter
15+ import androidx.compose.ui.graphics.toolingGraphicsLayer
16+ import androidx.compose.ui.graphics.vector.ImageVector
17+ import androidx.compose.ui.graphics.vector.rememberVectorPainter
18+ import androidx.compose.ui.layout.ContentScale
19+ import androidx.compose.ui.semantics.Role
20+ import androidx.compose.ui.semantics.contentDescription
21+ import androidx.compose.ui.semantics.role
22+ import androidx.compose.ui.semantics.semantics
23+ import androidx.compose.ui.unit.dp
24+ import top.yukonga.miuix.kmp.theme.MiuixTheme
25+
26+ /* *
27+ * A [Icon] component that draws [imageVector] using [tint], with a default value.
28+ *
29+ * @param imageVector [ImageVector] to draw inside this icon
30+ * @param contentDescription text used by accessibility services to describe what this icon
31+ * represents. This should always be provided unless this icon is used for decorative purposes,
32+ * and does not represent a meaningful action that a user can take. This text should be localized,
33+ * such as by using [androidx.compose.ui.res.stringResource] or similar
34+ * @param modifier the [Modifier] to be applied to this icon
35+ * @param tint tint to be applied to [imageVector]. If [Color.Unspecified] is provided, then no tint
36+ * is applied.
37+ */
38+ @Composable
39+ fun Icon (
40+ imageVector : ImageVector ,
41+ contentDescription : String? ,
42+ modifier : Modifier = Modifier ,
43+ tint : Color = MiuixTheme .colorScheme.onBackground
44+ ) {
45+ Icon (
46+ painter = rememberVectorPainter(imageVector),
47+ contentDescription = contentDescription,
48+ modifier = modifier,
49+ tint = tint
50+ )
51+ }
52+
53+ /* *
54+ * A [Icon] component that draws [bitmap] using [tint], with a default value.
55+ *
56+ * @param bitmap [ImageBitmap] to draw inside this icon
57+ * @param contentDescription text used by accessibility services to describe what this icon
58+ * represents. This should always be provided unless this icon is used for decorative purposes,
59+ * and does not represent a meaningful action that a user can take. This text should be localized,
60+ * such as by using [androidx.compose.ui.res.stringResource] or similar
61+ * @param modifier the [Modifier] to be applied to this icon
62+ * @param tint tint to be applied to [bitmap]. If [Color.Unspecified] is provided, then no tint is
63+ * applied.
64+ */
65+ @Composable
66+ fun Icon (
67+ bitmap : ImageBitmap ,
68+ contentDescription : String? ,
69+ modifier : Modifier = Modifier ,
70+ tint : Color = MiuixTheme .colorScheme.onBackground
71+ ) {
72+ val painter = remember(bitmap) { BitmapPainter (bitmap) }
73+ Icon (
74+ painter = painter,
75+ contentDescription = contentDescription,
76+ modifier = modifier,
77+ tint = tint
78+ )
79+ }
80+
81+ /* *
82+ * A [Icon] component that draws [painter] using [tint], with a default value.
83+ *
84+ * @param painter [Painter] to draw inside this icon
85+ * @param contentDescription text used by accessibility services to describe what this icon
86+ * represents. This should always be provided unless this icon is used for decorative purposes,
87+ * and does not represent a meaningful action that a user can take. This text should be localized,
88+ * such as by using [androidx.compose.ui.res.stringResource] or similar
89+ * @param modifier the [Modifier] to be applied to this icon
90+ * @param tint tint to be applied to [painter]. If [Color.Unspecified] is provided, then no tint is
91+ * applied.
92+ */
93+ @Composable
94+ fun Icon (
95+ painter : Painter ,
96+ contentDescription : String? ,
97+ modifier : Modifier = Modifier ,
98+ tint : Color = MiuixTheme .colorScheme.onBackground
99+ ) {
100+ val colorFilter =
101+ remember(tint) { if (tint == Color .Unspecified ) null else ColorFilter .tint(tint) }
102+ val semantics =
103+ if (contentDescription != null ) {
104+ Modifier .semantics {
105+ this .contentDescription = contentDescription
106+ this .role = Role .Image
107+ }
108+ } else {
109+ Modifier
110+ }
111+ Box (
112+ modifier
113+ .toolingGraphicsLayer()
114+ .defaultSizeFor(painter)
115+ .paint(painter, colorFilter = colorFilter, contentScale = ContentScale .Fit )
116+ .then(semantics)
117+ )
118+ }
119+
120+ private fun Modifier.defaultSizeFor (painter : Painter ) =
121+ this .then(
122+ if (painter.intrinsicSize == Size .Unspecified || painter.intrinsicSize.isInfinite()) {
123+ DefaultIconSizeModifier
124+ } else {
125+ Modifier
126+ }
127+ )
128+
129+ private fun Size.isInfinite () = width.isInfinite() && height.isInfinite()
130+
131+ // Default icon size, for icons with no intrinsic size information
132+ private val DefaultIconSizeModifier = Modifier .size(24 .dp)
0 commit comments