@@ -1501,7 +1501,9 @@ public final class GtkBackend: AppBackend {
15011501 }
15021502
15031503 public func createDatePicker( ) -> Widget {
1504- return TimePicker ( )
1504+ let widget = Gtk . Calendar ( )
1505+ widget. date = Date ( )
1506+ return widget
15051507 }
15061508
15071509 public func updateDatePicker(
@@ -1512,12 +1514,18 @@ public final class GtkBackend: AppBackend {
15121514 components: DatePickerComponents ,
15131515 onChange: @escaping ( Date ) -> Void
15141516 ) {
1515- let timePicker = datePicker as! TimePicker
1516- timePicker. update (
1517- calendar: environment. calendar,
1518- date: date,
1519- showSeconds: components. contains ( . hourMinuteAndSecond)
1520- )
1517+ if components. contains ( . hourAndMinute) {
1518+ print ( " Warning: time picker is unimplemented on GtkBackend " )
1519+ }
1520+ if environment. datePickerStyle == . wheel || environment. datePickerStyle == . compact {
1521+ print ( " Warning: only datePickerStyle.graphical is implemented in GtkBackend " )
1522+ }
1523+
1524+ let calendarWidget = datePicker as! Gtk . Calendar
1525+ calendarWidget. date = date
1526+ calendarWidget. daySelected = { calendarWidget in
1527+ onChange ( calendarWidget. date)
1528+ }
15211529 }
15221530
15231531 // MARK: Helpers
@@ -1602,6 +1610,9 @@ class CustomListBox: ListBox {
16021610 var cachedSelection : Int ? = nil
16031611}
16041612
1613+ // This kinda sorta works. Beyond the fact that it never shows the AM/PM picker, the SpinButtons
1614+ // don't behave correctly on change, and calendar.date(bySetting:value:of:) doesn't do what we need
1615+ // it to do.
16051616final class TimePicker : Box {
16061617 private var hourCycle : Locale . HourCycle
16071618 private let hourPicker : SpinButton
@@ -1611,6 +1622,8 @@ final class TimePicker: Box {
16111622 private var secondPicker : SpinButton ?
16121623 private var amPmPicker : DropDown ?
16131624
1625+ var onChange : ( ( Date ) -> Void ) ?
1626+
16141627 init ( ) {
16151628 let hourCycle = Locale . current. hourCycle
16161629
@@ -1621,14 +1634,14 @@ final class TimePicker: Box {
16211634 step: 1
16221635 )
16231636
1624- super. init ( orientation : . horizontal , spacing : 0 )
1637+ super. init ( gtk_box_new ( GTK_ORIENTATION_HORIZONTAL , 0 ) )
16251638
16261639 self . hourPicker. wrap = true
16271640 self . hourPicker. orientation = . vertical
1641+ self . hourPicker. numeric = true
16281642 self . minutePicker. wrap = true
16291643 self . minutePicker. orientation = . vertical
1630-
1631- self . orientation = . horizontal
1644+ self . minutePicker. numeric = true
16321645
16331646 self . add ( self . hourPicker)
16341647 self . add ( self . hourMinuteSeparator)
@@ -1643,6 +1656,9 @@ final class TimePicker: Box {
16431656 switch hourCycle {
16441657 case . zeroToEleven, . zeroToTwentyThree: 0
16451658 case . oneToTwelve, . oneToTwentyFour: 1
1659+ #if os(macOS)
1660+ @unknown default : fatalError ( )
1661+ #endif
16461662 }
16471663 }
16481664
@@ -1652,6 +1668,9 @@ final class TimePicker: Box {
16521668 case . oneToTwelve: 12
16531669 case . zeroToTwentyThree: 23
16541670 case . oneToTwentyFour: 24
1671+ #if os(macOS)
1672+ @unknown default : fatalError ( )
1673+ #endif
16551674 }
16561675 }
16571676
@@ -1672,7 +1691,9 @@ final class TimePicker: Box {
16721691 max: Double ( secondsRange. upperBound - 1 ) ,
16731692 step: 1
16741693 )
1675- secondPicker!. value = Double ( components. second!)
1694+ secondPicker!. numeric = true
1695+ secondPicker!. wrap = true
1696+ secondPicker!. text = " \( components. second!) "
16761697 insert ( child: minuteSecondSeparator!, after: minutePicker)
16771698 insert ( child: secondPicker!, after: minuteSecondSeparator!)
16781699 }
@@ -1688,11 +1709,19 @@ final class TimePicker: Box {
16881709 }
16891710
16901711 let minutesRange = calendar. range ( of: . minute, in: . hour, for: date) ?? 0 ..< 60
1691- minutePicker. value = Double ( components. minute!)
16921712 minutePicker. setRange (
16931713 min: Double ( minutesRange. lowerBound) ,
16941714 max: Double ( minutesRange. upperBound - 1 )
16951715 )
1716+ minutePicker. text = " \( components. minute!) "
1717+ minutePicker. valueChanged = { [ unowned self] minutePicker in
1718+ guard let value = Int ( exactly: minutePicker. value) ,
1719+ let newDate = calendar. date ( bySetting: . minute, value: value, of: date)
1720+ else {
1721+ return
1722+ }
1723+ self . onChange ? ( newDate)
1724+ }
16961725
16971726 let hoursRange = calendar. range ( of: . hour, in: . day, for: date)
16981727 self . hourCycle = ( calendar. locale ?? . current) . hourCycle
@@ -1720,6 +1749,17 @@ final class TimePicker: Box {
17201749 self . amPmPicker = nil
17211750 }
17221751 }
1752+
1753+ hourPicker. text =
1754+ " \( TimePicker . transformToRange ( components. hour!, hourCycle: self . hourCycle) ) "
1755+ hourPicker. valueChanged = { [ unowned self] hourPicker in
1756+ guard let value = Int ( exactly: hourPicker. value) ,
1757+ let newDate = calendar. date ( bySetting: . hour, value: value, of: date)
1758+ else {
1759+ return
1760+ }
1761+ self . onChange ? ( newDate)
1762+ }
17231763 }
17241764
17251765 private static func transformToRange( _ value: Int , hourCycle: Locale . HourCycle ) -> Int {
@@ -1728,9 +1768,9 @@ final class TimePicker: Box {
17281768 case . oneToTwelve: ( value + 11 ) % 12 + 1
17291769 case . zeroToTwentyThree: value % 24
17301770 case . oneToTwentyFour: ( value + 23 ) % 24 + 1
1771+ #if os(macOS)
1772+ @unknown default : fatalError ( )
1773+ #endif
17311774 }
17321775 }
17331776}
1734-
1735- final class DatePickerWidget : Box {
1736- }
0 commit comments