@@ -1500,6 +1500,26 @@ public final class GtkBackend: AppBackend {
15001500 }
15011501 }
15021502
1503+ public func createDatePicker( ) -> Widget {
1504+ return TimePicker ( )
1505+ }
1506+
1507+ public func updateDatePicker(
1508+ _ datePicker: Widget ,
1509+ environment: EnvironmentValues ,
1510+ date: Date ,
1511+ range: ClosedRange < Date > ,
1512+ components: DatePickerComponents ,
1513+ onChange: @escaping ( Date ) -> Void
1514+ ) {
1515+ let timePicker = datePicker as! TimePicker
1516+ timePicker. update (
1517+ calendar: environment. calendar,
1518+ date: date,
1519+ showSeconds: components. contains ( . hourMinuteAndSecond)
1520+ )
1521+ }
1522+
15031523 // MARK: Helpers
15041524
15051525 private func wrapInCustomRootContainer( _ widget: Widget ) -> Widget {
@@ -1635,37 +1655,80 @@ final class TimePicker: Box {
16351655 }
16361656 }
16371657
1638- func update( calendar: Calendar , date: Date , showSeconds: Bool ) {
1658+ func update( calendar: Foundation . Calendar , date: Date , showSeconds: Bool ) {
16391659 let components = calendar. dateComponents ( [ . hour, . minute, . second] , from: date)
16401660
16411661 if showSeconds {
1642- if let secondsPicker {
1643- // TODO update range
1662+ let secondsRange = calendar. range ( of: . second, in: . minute, for: date) ?? 0 ..< 60
1663+ if let secondPicker {
1664+ secondPicker. setRange (
1665+ min: Double ( secondsRange. lowerBound) ,
1666+ max: Double ( secondsRange. upperBound - 1 )
1667+ )
16441668 } else {
16451669 minuteSecondSeparator = Label ( string: " : " )
1646- let secondsRange = calendar. range ( of: . second, in: . minute, for: date) ?? 0 ..< 60
1647- secondsPicker = SpinButton (
1670+ secondPicker = SpinButton (
16481671 range: Double ( secondsRange. lowerBound) ,
16491672 max: Double ( secondsRange. upperBound - 1 ) ,
16501673 step: 1
16511674 )
1652- secondsPicker . value = Double ( components. second!)
1675+ secondPicker! . value = Double ( components. second!)
16531676 insert ( child: minuteSecondSeparator!, after: minutePicker)
1654- insert ( child: secondsPicker !, after: minuteSecondSeparator!)
1677+ insert ( child: secondPicker !, after: minuteSecondSeparator!)
16551678 }
16561679 } else {
16571680 if let minuteSecondSeparator {
16581681 remove ( minuteSecondSeparator)
16591682 self . minuteSecondSeparator = nil
16601683 }
1661- if let secondsPicker {
1662- remove ( secondsPicker )
1663- self . secondsPicker = nil
1684+ if let secondPicker {
1685+ remove ( secondPicker )
1686+ self . secondPicker = nil
16641687 }
16651688 }
16661689
1690+ let minutesRange = calendar. range ( of: . minute, in: . hour, for: date) ?? 0 ..< 60
16671691 minutePicker. value = Double ( components. minute!)
1668- // TODO update minutePicker's range and everything about the hour
1692+ minutePicker. setRange (
1693+ min: Double ( minutesRange. lowerBound) ,
1694+ max: Double ( minutesRange. upperBound - 1 )
1695+ )
1696+
1697+ let hoursRange = calendar. range ( of: . hour, in: . day, for: date)
1698+ self . hourCycle = ( calendar. locale ?? . current) . hourCycle
1699+ let effectiveHours = hoursRange? . map {
1700+ TimePicker . transformToRange ( $0, hourCycle: self . hourCycle)
1701+ }
1702+
1703+ hourPicker. setRange (
1704+ min: effectiveHours? . min ( ) . map ( Double . init ( _: ) )
1705+ ?? TimePicker . minHour ( for: self . hourCycle) ,
1706+ max: effectiveHours? . max ( ) . map ( Double . init ( _: ) )
1707+ ?? TimePicker . maxHour ( for: self . hourCycle)
1708+ )
1709+
1710+ if self . hourCycle == . oneToTwelve || self . hourCycle == . zeroToEleven {
1711+ if let amPmPicker {
1712+ // update strings if necessary
1713+ } else {
1714+ amPmPicker = DropDown ( strings: [ calendar. amSymbol, calendar. pmSymbol] )
1715+ add ( amPmPicker!)
1716+ }
1717+ } else {
1718+ if let amPmPicker {
1719+ remove ( amPmPicker)
1720+ self . amPmPicker = nil
1721+ }
1722+ }
1723+ }
1724+
1725+ private static func transformToRange( _ value: Int , hourCycle: Locale . HourCycle ) -> Int {
1726+ switch hourCycle {
1727+ case . zeroToEleven: value % 12
1728+ case . oneToTwelve: ( value + 11 ) % 12 + 1
1729+ case . zeroToTwentyThree: value % 24
1730+ case . oneToTwentyFour: ( value + 23 ) % 24 + 1
1731+ }
16691732 }
16701733}
16711734
0 commit comments