@@ -1581,3 +1581,93 @@ extension UnsafeMutablePointer {
15811581class CustomListBox : ListBox {
15821582 var cachedSelection : Int ? = nil
15831583}
1584+
1585+ final class TimePicker : Box {
1586+ private var hourCycle : Locale . HourCycle
1587+ private let hourPicker : SpinButton
1588+ private let hourMinuteSeparator = Label ( string: " : " )
1589+ private let minutePicker = SpinButton ( range: 0 , max: 59 , step: 1 )
1590+ private var minuteSecondSeparator : Label ?
1591+ private var secondPicker : SpinButton ?
1592+ private var amPmPicker : DropDown ?
1593+
1594+ init ( ) {
1595+ let hourCycle = Locale . current. hourCycle
1596+
1597+ self . hourCycle = hourCycle
1598+ self . hourPicker = SpinButton (
1599+ range: TimePicker . minHour ( for: hourCycle) ,
1600+ max: TimePicker . maxHour ( for: hourCycle) ,
1601+ step: 1
1602+ )
1603+
1604+ super. init ( orientation: . horizontal, spacing: 0 )
1605+
1606+ self . hourPicker. wrap = true
1607+ self . hourPicker. orientation = . vertical
1608+ self . minutePicker. wrap = true
1609+ self . minutePicker. orientation = . vertical
1610+
1611+ self . orientation = . horizontal
1612+
1613+ self . add ( self . hourPicker)
1614+ self . add ( self . hourMinuteSeparator)
1615+ self . add ( self . minutePicker)
1616+ }
1617+
1618+ func setEnabled( to isEnabled: Bool ) {
1619+ hourPicker. sensitive = isEnabled
1620+ }
1621+
1622+ private static func minHour( for hourCycle: Locale . HourCycle ) -> Double {
1623+ switch hourCycle {
1624+ case . zeroToEleven, . zeroToTwentyThree: 0
1625+ case . oneToTwelve, . oneToTwentyFour: 1
1626+ }
1627+ }
1628+
1629+ private static func maxHour( for hourCycle: Locale . HourCycle ) -> Double {
1630+ switch hourCycle {
1631+ case . zeroToEleven: 11
1632+ case . oneToTwelve: 12
1633+ case . zeroToTwentyThree: 23
1634+ case . oneToTwentyFour: 24
1635+ }
1636+ }
1637+
1638+ func update( calendar: Calendar , date: Date , showSeconds: Bool ) {
1639+ let components = calendar. dateComponents ( [ . hour, . minute, . second] , from: date)
1640+
1641+ if showSeconds {
1642+ if let secondsPicker {
1643+ // TODO update range
1644+ } else {
1645+ minuteSecondSeparator = Label ( string: " : " )
1646+ let secondsRange = calendar. range ( of: . second, in: . minute, for: date) ?? 0 ..< 60
1647+ secondsPicker = SpinButton (
1648+ range: Double ( secondsRange. lowerBound) ,
1649+ max: Double ( secondsRange. upperBound - 1 ) ,
1650+ step: 1
1651+ )
1652+ secondsPicker. value = Double ( components. second!)
1653+ insert ( child: minuteSecondSeparator!, after: minutePicker)
1654+ insert ( child: secondsPicker!, after: minuteSecondSeparator!)
1655+ }
1656+ } else {
1657+ if let minuteSecondSeparator {
1658+ remove ( minuteSecondSeparator)
1659+ self . minuteSecondSeparator = nil
1660+ }
1661+ if let secondsPicker {
1662+ remove ( secondsPicker)
1663+ self . secondsPicker = nil
1664+ }
1665+ }
1666+
1667+ minutePicker. value = Double ( components. minute!)
1668+ // TODO update minutePicker's range and everything about the hour
1669+ }
1670+ }
1671+
1672+ final class DatePickerWidget : Box {
1673+ }
0 commit comments