forked from microsoft/fluentui-android
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ProgressText.kt
122 lines (120 loc) · 5.52 KB
/
ProgressText.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package com.microsoft.fluentui.tokenized.progress
import androidx.compose.animation.core.LinearOutSlowInEasing
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicText
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import com.microsoft.fluentui.theme.FluentTheme
import com.microsoft.fluentui.theme.token.ControlTokens
import com.microsoft.fluentui.theme.token.FluentIcon
import com.microsoft.fluentui.theme.token.Icon
import com.microsoft.fluentui.theme.token.controlTokens.ProgressTextInfo
import com.microsoft.fluentui.theme.token.controlTokens.ProgressTextTokens
import com.microsoft.fluentui.util.dpToPx
/**
* ProgressTexts are used to give information through a text about the current progress.
* A ProgressText consists of a Text and a progressbar.
* @param text Text or info to display
* @param progress Progress of the progress indicator. 0.0 represents no progress and 1.0 represents full progress.
* @param leadingIconAccessory Add an optional leading icon.
* @param modifier Modifier for the progress text
* @param progressTextTokens Token values for the ProgressText
*/
@Composable
fun ProgressText(
text: String,
progress: Float,
leadingIconAccessory: FluentIcon? = null,
modifier: Modifier = Modifier,
progressTextTokens: ProgressTextTokens? = null
) {
val themeID =
FluentTheme.themeID //Adding This only for recomposition in case of Token Updates. Unused otherwise.
val tokens = progressTextTokens
?: FluentTheme.controlTokens.tokens[ControlTokens.ControlType.ProgressTextControlType] as ProgressTextTokens
val progressTextInfo = ProgressTextInfo(progress)
val currentProgress = animateFloatAsState(
targetValue = progress.coerceIn(0f..1f), animationSpec = tween(
delayMillis = 0, durationMillis = 1000, easing = LinearOutSlowInEasing
)
)
val backgroundBrush = tokens.backgroundBrush(progressTextInfo = progressTextInfo)
val border = tokens.borderWidth(progressTextInfo = progressTextInfo)
val borderColor = tokens.borderColor(progressTextInfo = progressTextInfo)
val typography = tokens.typography(progressTextInfo = progressTextInfo)
val textColor = tokens.textColor(progressTextInfo = progressTextInfo)
val progressIndicatorHeight = tokens.progressbarHeight(progressTextInfo = progressTextInfo)
val progressIndicatorBackgroundColor =
tokens.progressbarBackgroundColor(progressTextInfo = progressTextInfo)
val progressIndicatorBrush = tokens.progressbarBrush(progressTextInfo = progressTextInfo)
val iconTextSpacing = tokens.iconTextSpacing(progressTextInfo = progressTextInfo)
val padding = tokens.padding(progressTextInfo = progressTextInfo)
val iconSize = tokens.iconSize(progressTextInfo = progressTextInfo)
val iconColor = tokens.iconColor(progressTextInfo = progressTextInfo)
val shape = RoundedCornerShape(12.dp)
Box(modifier = Modifier.clip(shape)) {
Box(
modifier = modifier
.background(
backgroundBrush, shape
)
.border(
border, borderColor, shape
)
) {
Row(
modifier = Modifier.padding(padding),
verticalAlignment = Alignment.CenterVertically
) {
if (leadingIconAccessory != null) {
Icon(modifier = Modifier.size(iconSize), icon = leadingIconAccessory, tint = iconColor)
Spacer(modifier = Modifier.width(iconTextSpacing))
}
BasicText(text = text, style = typography.merge(TextStyle(color = textColor)))
}
}
Box(modifier = Modifier.align(Alignment.BottomCenter)) {
Canvas(
modifier = modifier
.fillMaxWidth()
.requiredHeight(progressIndicatorHeight)
.progressSemantics(progress)
.testTag("progressBar")
) {
val strokeWidth = dpToPx(progressIndicatorHeight)
val yOffset = strokeWidth / 2
val isLtr = layoutDirection == LayoutDirection.Ltr
val barStart = (if (isLtr) 0f else size.width)
val barEnd = (if (isLtr) size.width else 0f)
drawLine(
progressIndicatorBackgroundColor,
Offset(barStart, yOffset),
Offset(barEnd, yOffset),
strokeWidth
)
val progressIndicatorWidth = currentProgress.value * size.width
val indicatorLineEnd =
if (isLtr) progressIndicatorWidth else size.width - progressIndicatorWidth
drawLine(
progressIndicatorBrush,
Offset(barStart, yOffset),
Offset(indicatorLineEnd, yOffset),
strokeWidth,
StrokeCap.Round
)
}
}
}
}