Skip to content

Commit

Permalink
UI: Make reusable timeline component (#245)
Browse files Browse the repository at this point in the history
  • Loading branch information
ksharma-xyz authored Oct 23, 2024
1 parent 60ec6ab commit 8bc7099
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,8 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
Expand Down Expand Up @@ -104,28 +100,20 @@ fun LegView(
time = stops.first().time,
name = stops.first().name,
modifier = Modifier
.drawBehind {
drawCircle(
color = transportModeLine.transportMode.colorCode.hexToComposeColor(),
radius = circleRadius.toPx(),
center = Offset(0f, 38.sp.toPx() / 2),
)
drawLine(
brush = Brush.linearGradient(
colors = listOf(
transportModeLine.transportMode.colorCode.hexToComposeColor(),
transportModeLine.transportMode.colorCode.hexToComposeColor(),
),
),
start = Offset(
x = 0f,
y = 38.sp.toPx() / 2,
),
end = Offset(x = 0f, y = this.size.height),
strokeWidth = strokeWidth.toPx(),
cap = StrokeCap.Round,
)
}
.timeLineTop(
color = transportModeLine.transportMode.colorCode.hexToComposeColor(),
strokeWidth = strokeWidth,
circleRadius = circleRadius,
)
.padding(start = 16.dp),
)

Column(
modifier = Modifier
.timeLineCenter(
color = transportModeLine.transportMode.colorCode.hexToComposeColor(),
strokeWidth = strokeWidth,
)
.padding(start = 16.dp),
) {
if (stops.size > 2) {
Expand All @@ -149,25 +137,11 @@ fun LegView(
time = stops.last().time,
name = stops.last().name,
modifier = Modifier
.drawBehind {
drawLine(
brush = Brush.linearGradient(
colors = listOf(
transportModeLine.transportMode.colorCode.hexToComposeColor(),
transportModeLine.transportMode.colorCode.hexToComposeColor(),
),
),
start = Offset(x = 0f, y = 0f),
end = Offset(x = 0f, y = this.size.height - 38.dp.toPx() / 2),
strokeWidth = strokeWidth.toPx(),
cap = StrokeCap.Round,
)
drawCircle(
color = transportModeLine.transportMode.colorCode.hexToComposeColor(),
radius = circleRadius.toPx(),
center = Offset(0f, this.size.height - 38.sp.toPx() / 2),
)
}
.timeLineBottom(
color = transportModeLine.transportMode.colorCode.hexToComposeColor(),
strokeWidth = strokeWidth,
circleRadius = circleRadius,
)
.padding(start = 16.dp),
)
}
Expand All @@ -179,7 +153,6 @@ fun ProminentStopInfo(
time: String,
name: String,
modifier: Modifier = Modifier,
content: @Composable () -> Unit = {},
) {
Column(modifier = modifier) {
Text(
Expand All @@ -192,7 +165,6 @@ fun ProminentStopInfo(
style = KrailTheme.typography.titleSmall,
color = KrailTheme.colors.onSurface,
)
content()
}
}

Expand Down Expand Up @@ -229,6 +201,8 @@ fun StopsRow(stops: String, line: TransportModeLine, modifier: Modifier = Modifi
}
}

// region Previews

@PreviewLightDark
@Preview(fontScale = 2f)
@Composable
Expand Down Expand Up @@ -312,3 +286,5 @@ private fun PreviewProminentStopInfo() {
)
}
}

// endregion
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package xyz.ksharma.krail.trip.planner.ui.components

import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.unit.Dp

/**
* Draws a vertical line and a circle at the top start of the composable,
* representing the top of a timeline element.
*
* @param color The color of the line and circle.
* @param strokeWidth The width of the line stroke.
* @param circleRadius The radius of the circle.
* @return A [Modifier] that draws the line and circle.
*/
internal fun Modifier.timeLineTop(color: Color, strokeWidth: Dp, circleRadius: Dp): Modifier {
return this.drawBehind {
drawCircle(
color = color,
radius = circleRadius.toPx(),
center = Offset(x = 0f, y = this.size.height / 2),
)
drawLine(
color = color,
start = Offset(x = 0f, y = this.size.height / 2),
end = Offset(x = 0f, y = this.size.height),
strokeWidth = strokeWidth.toPx(),
cap = StrokeCap.Round,
)
}
}

/**
* Draws a vertical line through the center start of the composable,
* representing a continuous timeline element.
*
* @param color The color of the line.
* @param strokeWidth The width of the line stroke.
* @return A [Modifier] that draws the line.
*/
internal fun Modifier.timeLineCenter(color: Color, strokeWidth: Dp): Modifier {
return this.drawBehind {
drawLine(
color = color,
start = Offset(x = 0f, y = 0f),
end = Offset(x = 0f, y = this.size.height),
strokeWidth = strokeWidth.toPx(),
cap = StrokeCap.Round,
)
}
}

/**
* Draws a vertical line and a circle at the bottom start of the composable,
* representing the bottom end of a timeline element.
*
* @param color The color of the line and circle.
* @param strokeWidth The width of the line stroke.
* @param circleRadius The radius of the circle.
* @return A [Modifier] that draws the line and circle.
*/
internal fun Modifier.timeLineBottom(color: Color, strokeWidth: Dp, circleRadius: Dp): Modifier {
return this.drawBehind {
drawLine(
color = color,
start = Offset(x = 0f, y = 0f),
end = Offset(x = 0f, y = this.size.height / 2),
strokeWidth = strokeWidth.toPx(),
cap = StrokeCap.Round,
)
drawCircle(
color = color,
radius = circleRadius.toPx(),
center = Offset(0f, this.size.height / 2),
)
}
}

0 comments on commit 8bc7099

Please sign in to comment.