@@ -7,7 +7,6 @@ import androidx.compose.animation.shrinkVertically
77import androidx.compose.foundation.background
88import androidx.compose.foundation.layout.Arrangement
99import androidx.compose.foundation.layout.Box
10- import androidx.compose.foundation.layout.BoxWithConstraints
1110import androidx.compose.foundation.layout.Column
1211import androidx.compose.foundation.layout.Row
1312import androidx.compose.foundation.layout.Spacer
@@ -23,13 +22,19 @@ import androidx.compose.material.Card
2322import androidx.compose.material.MaterialTheme
2423import androidx.compose.material.Text
2524import androidx.compose.runtime.Composable
25+ import androidx.compose.runtime.getValue
26+ import androidx.compose.runtime.mutableFloatStateOf
27+ import androidx.compose.runtime.mutableIntStateOf
28+ import androidx.compose.runtime.remember
29+ import androidx.compose.runtime.setValue
2630import androidx.compose.ui.Alignment
2731import androidx.compose.ui.Modifier
2832import androidx.compose.ui.draw.clip
2933import androidx.compose.ui.draw.drawWithContent
3034import androidx.compose.ui.geometry.Offset
3135import androidx.compose.ui.geometry.Size
3236import androidx.compose.ui.graphics.Color
37+ import androidx.compose.ui.layout.onSizeChanged
3338import androidx.compose.ui.platform.LocalDensity
3439import androidx.compose.ui.platform.testTag
3540import androidx.compose.ui.res.stringResource
@@ -41,6 +46,7 @@ import androidx.compose.ui.tooling.preview.Preview
4146import androidx.compose.ui.unit.IntOffset
4247import androidx.compose.ui.unit.dp
4348import androidx.compose.ui.unit.sp
49+ import androidx.compose.ui.unit.toSize
4450import org.simple.clinic.R
4551import org.simple.clinic.common.ui.components.FilledButton
4652import org.simple.clinic.common.ui.theme.SimpleInverseTheme
@@ -72,55 +78,61 @@ fun StatinNudge(
7278 Card (
7379 modifier = modifier
7480 ) {
75- BoxWithConstraints (
76- modifier = Modifier .padding(16 .dp)
81+ var startOffset by remember { mutableFloatStateOf(0f ) }
82+ var endOffset by remember { mutableFloatStateOf(0f ) }
83+ var columnWidth by remember { mutableIntStateOf(0 ) }
84+
85+ Column (
86+ modifier = Modifier
87+ .padding(16 .dp)
88+ .onSizeChanged { intSize ->
89+ val size = intSize.toSize()
90+ val (start, end) = getOffsets(statinInfo.cvdRisk, size)
91+ startOffset = start
92+ endOffset = end
93+ columnWidth = intSize.width
94+ }
7795 ) {
78- val constraints = constraints
79- val size = Size (constraints.maxWidth.toFloat(), constraints.maxHeight.toFloat())
80- val (startOffset, endOffset) = getOffsets(statinInfo.cvdRisk, size)
81-
82- Column {
83- RiskText (
84- startOffset = startOffset,
85- endOffset = endOffset,
96+ RiskText (
97+ startOffset = startOffset,
98+ endOffset = endOffset,
99+ statinInfo = statinInfo,
100+ parentWidth = columnWidth,
101+ )
102+ Spacer (modifier = Modifier .height(12 .dp))
103+ RiskProgressBar (
104+ startOffset = startOffset,
105+ endOffset = endOffset
106+ )
107+ Spacer (modifier = Modifier .height(16 .dp))
108+ DescriptionText (
109+ isLabBasedStatinNudgeEnabled = isLabBasedStatinNudgeEnabled,
110+ isNonLabBasedStatinNudgeEnabled = isNonLabBasedStatinNudgeEnabled,
111+ statinInfo = statinInfo,
112+ useVeryHighRiskAsThreshold = useVeryHighRiskAsThreshold
113+ )
114+
115+ val shouldShowButtonsForNonLabNudge = isNonLabBasedStatinNudgeEnabled && ! statinInfo.hasDiabetes
116+ val shouldShowButtonsForLabNudge = isLabBasedStatinNudgeEnabled &&
117+ statinInfo.cvdRisk?.canPrescribeStatin == true
118+
119+ val shouldShowAddButtons = ! statinInfo.hasCVD &&
120+ (shouldShowButtonsForNonLabNudge || shouldShowButtonsForLabNudge)
121+
122+ if (shouldShowAddButtons) {
123+ StainNudgeAddButtons (
86124 statinInfo = statinInfo,
87- parentWidth = constraints.maxWidth,
88- )
89- Spacer (modifier = Modifier .height(12 .dp))
90- RiskProgressBar (
91- startOffset = startOffset,
92- endOffset = endOffset
93- )
94- Spacer (modifier = Modifier .height(16 .dp))
95- DescriptionText (
96- isLabBasedStatinNudgeEnabled = isLabBasedStatinNudgeEnabled,
97125 isNonLabBasedStatinNudgeEnabled = isNonLabBasedStatinNudgeEnabled,
98- statinInfo = statinInfo,
99- useVeryHighRiskAsThreshold = useVeryHighRiskAsThreshold
126+ isLabBasedStatinNudgeEnabled = isLabBasedStatinNudgeEnabled,
127+ addTobaccoUseClicked = addTobaccoUseClicked,
128+ addBMIClick = addBMIClick,
129+ addCholesterol = addCholesterol,
100130 )
101-
102- val shouldShowButtonsForNonLabNudge = isNonLabBasedStatinNudgeEnabled && ! statinInfo.hasDiabetes
103- val shouldShowButtonsForLabNudge = isLabBasedStatinNudgeEnabled &&
104- statinInfo.cvdRisk?.canPrescribeStatin == true
105-
106- val shouldShowAddButtons = ! statinInfo.hasCVD &&
107- (shouldShowButtonsForNonLabNudge || shouldShowButtonsForLabNudge)
108-
109- if (shouldShowAddButtons) {
110- StainNudgeAddButtons (
111- modifier = Modifier .padding(top = 16 .dp),
112- statinInfo = statinInfo,
113- isNonLabBasedStatinNudgeEnabled = isNonLabBasedStatinNudgeEnabled,
114- isLabBasedStatinNudgeEnabled = isLabBasedStatinNudgeEnabled,
115- addTobaccoUseClicked = addTobaccoUseClicked,
116- addBMIClick = addBMIClick,
117- addCholesterol = addCholesterol,
118- )
119- }
120131 }
121132 }
122133 }
123134 }
135+ // }
124136}
125137
126138@Composable
@@ -171,15 +183,15 @@ fun RiskText(
171183
172184 Text (
173185 modifier = Modifier
174- .testTag(" STATIN_NUDGE_RISK_TEXT" )
175- .offset {
176- IntOffset (
177- x = clampedOffsetX.toInt(),
178- y = 0
179- )
180- }
181- .background(riskColor, shape = RoundedCornerShape (50 ))
182- .padding(horizontal = 8 .dp, vertical = 4 .dp),
186+ .testTag(" STATIN_NUDGE_RISK_TEXT" )
187+ .offset {
188+ IntOffset (
189+ x = clampedOffsetX.toInt(),
190+ y = 0
191+ )
192+ }
193+ .background(riskColor, shape = RoundedCornerShape (50 ))
194+ .padding(horizontal = 8 .dp, vertical = 4 .dp),
183195 style = SimpleTheme .typography.material.button,
184196 color = SimpleTheme .colors.onToolbarPrimary,
185197 text = riskText
@@ -200,64 +212,70 @@ fun RiskProgressBar(
200212 )
201213
202214 val indicatorColor = Color (0xFF2F363D )
215+ var progressBarWidth by remember { mutableFloatStateOf(0f ) }
203216
204- BoxWithConstraints (
217+ Box (
205218 modifier = Modifier
206- .fillMaxWidth()
207- .height(14 .dp)
208- .drawWithContent {
209- drawContent()
210-
211- drawLine(
212- color = indicatorColor,
213- start = Offset (startOffset, 0f ),
214- end = Offset (startOffset, size.height),
215- strokeWidth = 2 .dp.toPx()
216- )
217- drawLine(
218- color = indicatorColor,
219- start = Offset (endOffset, 0f ),
220- end = Offset (endOffset, size.height),
221- strokeWidth = 2 .dp.toPx()
222- )
223- },
219+ .fillMaxWidth()
220+ .height(14 .dp)
221+ .onSizeChanged { intSize ->
222+ progressBarWidth = intSize.width.toFloat()
223+ }
224+ .drawWithContent {
225+ drawContent()
226+
227+ drawLine(
228+ color = indicatorColor,
229+ start = Offset (startOffset, 0f ),
230+ end = Offset (startOffset, size.height),
231+ strokeWidth = 2 .dp.toPx()
232+ )
233+ drawLine(
234+ color = indicatorColor,
235+ start = Offset (endOffset, 0f ),
236+ end = Offset (endOffset, size.height),
237+ strokeWidth = 2 .dp.toPx()
238+ )
239+ },
224240 contentAlignment = Alignment .Center ,
225241 ) {
226- val totalSegments = riskColors.size
227- val segmentWidthPx = constraints.maxWidth.toFloat() / totalSegments
228-
229- Row (
230- modifier = Modifier
231- .fillMaxWidth()
232- .height(4 .dp)
233- .clip(RoundedCornerShape (50 ))
234- ) {
235- riskColors.forEachIndexed { index, color ->
236- val segmentStartPx = index * segmentWidthPx
237- val segmentEndPx = (index + 1 ) * segmentWidthPx
238-
239- Box (
240- modifier = Modifier
241- .weight(1f )
242- .fillMaxHeight()
243- .drawWithContent {
244- drawRect(color.copy(alpha = 0.5f ))
245-
246- val visibleStart = maxOf(segmentStartPx, startOffset)
247- val visibleEnd = minOf(segmentEndPx, endOffset)
248-
249- if (visibleStart < visibleEnd) {
250- drawRect(
251- color = color.copy(alpha = 1.0f ),
252- topLeft = Offset (x = visibleStart - segmentStartPx, y = 0f ),
253- size = Size (
254- width = visibleEnd - visibleStart,
255- height = size.height
256- )
257- )
258- }
259- }
260- )
242+ if (progressBarWidth > 0f ) {
243+ val totalSegments = riskColors.size
244+ val segmentWidthPx = progressBarWidth / totalSegments
245+
246+ Row (
247+ modifier = Modifier
248+ .fillMaxWidth()
249+ .height(4 .dp)
250+ .clip(RoundedCornerShape (50 ))
251+ ) {
252+ riskColors.forEachIndexed { index, color ->
253+ val segmentStartPx = index * segmentWidthPx
254+ val segmentEndPx = (index + 1 ) * segmentWidthPx
255+
256+ Box (
257+ modifier = Modifier
258+ .weight(1f )
259+ .fillMaxHeight()
260+ .drawWithContent {
261+ drawRect(color.copy(alpha = 0.5f ))
262+
263+ val visibleStart = maxOf(segmentStartPx, startOffset)
264+ val visibleEnd = minOf(segmentEndPx, endOffset)
265+
266+ if (visibleStart < visibleEnd) {
267+ drawRect(
268+ color = color.copy(alpha = 1.0f ),
269+ topLeft = Offset (x = visibleStart - segmentStartPx, y = 0f ),
270+ size = Size (
271+ width = visibleEnd - visibleStart,
272+ height = size.height
273+ )
274+ )
275+ }
276+ }
277+ )
278+ }
261279 }
262280 }
263281 }
@@ -293,7 +311,6 @@ fun DescriptionText(
293311
294312@Composable
295313fun StainNudgeAddButtons (
296- modifier : Modifier = Modifier ,
297314 statinInfo : StatinInfo ,
298315 isNonLabBasedStatinNudgeEnabled : Boolean ,
299316 isLabBasedStatinNudgeEnabled : Boolean ,
@@ -303,15 +320,16 @@ fun StainNudgeAddButtons(
303320) {
304321 SimpleInverseTheme {
305322 Row (
306- modifier = modifier .fillMaxWidth(),
323+ modifier = Modifier .fillMaxWidth(),
307324 horizontalArrangement = Arrangement .spacedBy(8 .dp)
308325 ) {
309326 if (statinInfo.isSmoker == Answer .Unanswered ) {
310327 StainNudgeAddButton (
311328 text = stringResource(R .string.statin_alert_add_tobacco_use),
312329 modifier = Modifier
313- .testTag(" STATIN_NUDGE_ADD_TOBACCO_USE" )
314- .weight(1f ),
330+ .padding(top = 16 .dp)
331+ .testTag(" STATIN_NUDGE_ADD_TOBACCO_USE" )
332+ .weight(1f ),
315333 onClick = addTobaccoUseClicked
316334 )
317335 }
@@ -320,8 +338,9 @@ fun StainNudgeAddButtons(
320338 StainNudgeAddButton (
321339 text = stringResource(R .string.statin_alert_add_bmi),
322340 modifier = Modifier
323- .testTag(" STATIN_NUDGE_ADD_BMI" )
324- .weight(1f ),
341+ .padding(top = 16 .dp)
342+ .testTag(" STATIN_NUDGE_ADD_BMI" )
343+ .weight(1f ),
325344 onClick = addBMIClick
326345 )
327346 }
@@ -330,8 +349,9 @@ fun StainNudgeAddButtons(
330349 StainNudgeAddButton (
331350 text = stringResource(R .string.statin_alert_add_cholesterol),
332351 modifier = Modifier
333- .testTag(" STATIN_NUDGE_ADD_CHOLESTEROL" )
334- .weight(1f ),
352+ .padding(top = 16 .dp)
353+ .testTag(" STATIN_NUDGE_ADD_CHOLESTEROL" )
354+ .weight(1f ),
335355 onClick = addCholesterol
336356 )
337357 }
@@ -347,9 +367,9 @@ fun StainNudgeAddButton(
347367) {
348368 FilledButton (
349369 modifier = modifier
350- .height(36 .dp)
351- .fillMaxWidth()
352- .clip(RoundedCornerShape (50 )),
370+ .height(36 .dp)
371+ .fillMaxWidth()
372+ .clip(RoundedCornerShape (50 )),
353373 onClick = onClick
354374 ) {
355375 BasicText (
0 commit comments