1+ package com.commandiron.wheel_picker_compose.core
2+
3+ import androidx.compose.foundation.layout.Box
4+ import androidx.compose.foundation.layout.Row
5+ import androidx.compose.foundation.layout.size
6+ import androidx.compose.material3.LocalContentColor
7+ import androidx.compose.material3.MaterialTheme
8+ import androidx.compose.material3.Surface
9+ import androidx.compose.runtime.*
10+ import androidx.compose.ui.Alignment
11+ import androidx.compose.ui.Modifier
12+ import androidx.compose.ui.graphics.Color
13+ import androidx.compose.ui.text.TextStyle
14+ import androidx.compose.ui.unit.DpSize
15+ import androidx.compose.ui.unit.dp
16+ import java.security.acl.Group
17+ import java.time.LocalDateTime
18+ import java.time.format.DateTimeFormatter
19+ import java.time.temporal.ChronoUnit
20+
21+ @Composable
22+ internal fun GroupedWheelDateTimePicker (
23+ modifier : Modifier = Modifier ,
24+ startDateTime : LocalDateTime = LocalDateTime .now(),
25+ minDateTime : LocalDateTime = LocalDateTime .MIN ,
26+ maxDateTime : LocalDateTime = LocalDateTime .MAX ,
27+ todayLabel : String? = null,
28+ dateFormat : DateTimeFormatter = DateTimeFormatter .ofPattern("dd.MM .yyyy"),
29+ timeFormat : TimeFormat = TimeFormat .HOUR_24 ,
30+ size : DpSize = DpSize (256.dp, 128.dp),
31+ rowCount : Int = 3,
32+ textStyle : TextStyle = MaterialTheme .typography.titleMedium,
33+ textColor : Color = LocalContentColor .current,
34+ selectorProperties : SelectorProperties = WheelPickerDefaults .selectorProperties(),
35+ onDateTime : (snappedDateTime: GroupedDateTime ) -> Unit = {}
36+ ) {
37+ var snappedDateTime by remember { mutableStateOf(startDateTime.truncatedTo(ChronoUnit .MINUTES )) }
38+
39+ Box (modifier = modifier, contentAlignment = Alignment .Center ) {
40+ if (selectorProperties.enabled().value) {
41+ Surface (
42+ modifier = Modifier
43+ .size(size.width, size.height / rowCount),
44+ shape = selectorProperties.shape().value,
45+ color = selectorProperties.color().value,
46+ border = selectorProperties.border().value
47+ ) {}
48+ }
49+ Row {
50+ // Date
51+ GroupedWheelDatePicker (
52+ startDate = startDateTime.toLocalDate(),
53+ minDate = minDateTime.toLocalDate(),
54+ maxDate = maxDateTime.toLocalDate(),
55+ todayLabel = todayLabel,
56+ format = dateFormat,
57+ size = DpSize (
58+ width = size.width / 2 ,
59+ height = size.height
60+ ),
61+ rowCount = rowCount,
62+ textStyle = textStyle,
63+ textColor = textColor,
64+ selectorProperties = WheelPickerDefaults .selectorProperties(
65+ enabled = false
66+ ),
67+ onSnappedDate = { snappedDate ->
68+ val newDateTime = when (snappedDate) {
69+ is GroupedDate .Date -> {
70+ snappedDateTime
71+ .withDayOfMonth(snappedDate.groupedLocalDate.dayOfMonth)
72+ .withMonth(snappedDate.groupedLocalDate.monthValue)
73+ .withYear(snappedDate.groupedLocalDate.year)
74+ }
75+ }
76+
77+ if (! newDateTime.isBefore(minDateTime) && ! newDateTime.isAfter(maxDateTime)) {
78+ snappedDateTime = newDateTime
79+ }
80+
81+ onDateTime(GroupedDateTime .Date (snappedDateTime))
82+ }
83+ )
84+ // Time
85+ DefaultWheelTimePicker (
86+ startTime = startDateTime.toLocalTime(),
87+ timeFormat = timeFormat,
88+ size = DpSize (
89+ width = size.width / 2 ,
90+ height = size.height
91+ ),
92+ rowCount = rowCount,
93+ textStyle = textStyle,
94+ textColor = textColor,
95+ selectorProperties = WheelPickerDefaults .selectorProperties(
96+ enabled = false
97+ ),
98+ onSnappedTime = { snappedTime, timeFormat ->
99+ val newDateTime = when (snappedTime) {
100+ is SnappedTime .Hour -> {
101+ snappedDateTime.withHour(snappedTime.snappedLocalTime.hour)
102+ }
103+ is SnappedTime .Minute -> {
104+ snappedDateTime.withMinute(snappedTime.snappedLocalTime.minute)
105+ }
106+ }
107+
108+ if (! newDateTime.isBefore(minDateTime) && ! newDateTime.isAfter(maxDateTime)) {
109+ snappedDateTime = newDateTime
110+ }
111+
112+ return @DefaultWheelTimePicker when (snappedTime) {
113+ is SnappedTime .Hour -> {
114+ onDateTime(GroupedDateTime .Hour (snappedDateTime))
115+ if (timeFormat == TimeFormat .HOUR_24 ) snappedDateTime.hour else
116+ localTimeToAmPmHour(snappedDateTime.toLocalTime()) - 1
117+ }
118+ is SnappedTime .Minute -> {
119+ onDateTime(GroupedDateTime .Minute (snappedDateTime))
120+ snappedDateTime.minute
121+ }
122+ }
123+ }
124+ )
125+ }
126+ }
127+ }
0 commit comments