|
|
@@ -2738,17 +2738,17 @@ private extension ViewController {
|
|
2738
|
2738
|
filterRow.addArrangedSubview(filterDropdown)
|
|
2739
|
2739
|
filterRow.setCustomSpacing(20, after: filterDropdown)
|
|
2740
|
2740
|
|
|
2741
|
|
- let fromPicker = makeScheduleDatePicker(date: schedulePageFromDate)
|
|
|
2741
|
+ let (fromShell, fromPicker) = makeScheduleDatePicker(date: schedulePageFromDate)
|
|
2742
|
2742
|
schedulePageFromDatePicker = fromPicker
|
|
2743
|
|
- filterRow.addArrangedSubview(fromPicker)
|
|
2744
|
|
- filterRow.setCustomSpacing(16, after: fromPicker)
|
|
|
2743
|
+ filterRow.addArrangedSubview(fromShell)
|
|
|
2744
|
+ filterRow.setCustomSpacing(16, after: fromShell)
|
|
2745
|
2745
|
|
|
2746
|
|
- let toPicker = makeScheduleDatePicker(date: schedulePageToDate)
|
|
|
2746
|
+ let (toShell, toPicker) = makeScheduleDatePicker(date: schedulePageToDate)
|
|
2747
|
2747
|
schedulePageToDatePicker = toPicker
|
|
2748
|
|
- filterRow.addArrangedSubview(toPicker)
|
|
|
2748
|
+ filterRow.addArrangedSubview(toShell)
|
|
2749
|
2749
|
NSLayoutConstraint.activate([
|
|
2750
|
|
- fromPicker.widthAnchor.constraint(equalTo: toPicker.widthAnchor),
|
|
2751
|
|
- fromPicker.widthAnchor.constraint(greaterThanOrEqualToConstant: 152)
|
|
|
2750
|
+ fromShell.widthAnchor.constraint(equalTo: toShell.widthAnchor),
|
|
|
2751
|
+ fromShell.widthAnchor.constraint(greaterThanOrEqualToConstant: 152)
|
|
2752
|
2752
|
])
|
|
2753
|
2753
|
|
|
2754
|
2754
|
let filterRowSpacer = NSView()
|
|
|
@@ -2815,18 +2815,56 @@ private extension ViewController {
|
|
2815
|
2815
|
return button
|
|
2816
|
2816
|
}
|
|
2817
|
2817
|
|
|
2818
|
|
- private func makeScheduleDatePicker(date: Date) -> NSDatePicker {
|
|
|
2818
|
+ /// Rounded shell matching `makeSchedulePageFilterDropdown` (34pt, 8pt corner, border + hover). Both pickers use the same field+stepper style inside the shell.
|
|
|
2819
|
+ private func makeScheduleDatePicker(date: Date) -> (NSView, NSDatePicker) {
|
|
|
2820
|
+ let shell = HoverSurfaceView()
|
|
|
2821
|
+ shell.translatesAutoresizingMaskIntoConstraints = false
|
|
|
2822
|
+ shell.wantsLayer = true
|
|
|
2823
|
+ shell.layer?.cornerRadius = 8
|
|
|
2824
|
+ shell.layer?.masksToBounds = true
|
|
|
2825
|
+ shell.layer?.borderWidth = 1
|
|
|
2826
|
+
|
|
|
2827
|
+ let baseColor = palette.inputBackground
|
|
|
2828
|
+ let baseBorder = palette.inputBorder
|
|
|
2829
|
+ let hoverBlend = darkModeEnabled ? NSColor.white : NSColor.black
|
|
|
2830
|
+ let hoverBackground = baseColor.blended(withFraction: 0.10, of: hoverBlend) ?? baseColor
|
|
|
2831
|
+ let hoverBorder = baseBorder.blended(withFraction: 0.16, of: hoverBlend) ?? baseBorder
|
|
|
2832
|
+
|
|
|
2833
|
+ func applyShellIdleAppearance() {
|
|
|
2834
|
+ shell.layer?.backgroundColor = baseColor.cgColor
|
|
|
2835
|
+ shell.layer?.borderColor = baseBorder.cgColor
|
|
|
2836
|
+ }
|
|
|
2837
|
+ applyShellIdleAppearance()
|
|
|
2838
|
+
|
|
|
2839
|
+ shell.onHoverChanged = { [weak shell] hovering in
|
|
|
2840
|
+ guard let shell else { return }
|
|
|
2841
|
+ shell.layer?.backgroundColor = (hovering ? hoverBackground : baseColor).cgColor
|
|
|
2842
|
+ shell.layer?.borderColor = (hovering ? hoverBorder : baseBorder).cgColor
|
|
|
2843
|
+ }
|
|
|
2844
|
+
|
|
2819
|
2845
|
let picker = NSDatePicker()
|
|
2820
|
2846
|
picker.translatesAutoresizingMaskIntoConstraints = false
|
|
|
2847
|
+ picker.isBordered = false
|
|
|
2848
|
+ picker.drawsBackground = false
|
|
|
2849
|
+ picker.focusRingType = .none
|
|
2821
|
2850
|
picker.datePickerStyle = .textFieldAndStepper
|
|
2822
|
2851
|
picker.datePickerElements = [.yearMonthDay]
|
|
2823
|
2852
|
picker.dateValue = date
|
|
2824
|
2853
|
picker.font = typography.filterText
|
|
2825
|
|
- picker.heightAnchor.constraint(equalToConstant: 34).isActive = true
|
|
|
2854
|
+ picker.textColor = palette.textSecondary
|
|
2826
|
2855
|
picker.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
|
2827
|
2856
|
picker.target = self
|
|
2828
|
2857
|
picker.action = #selector(schedulePageDatePickerChanged(_:))
|
|
2829
|
|
- return picker
|
|
|
2858
|
+
|
|
|
2859
|
+ shell.addSubview(picker)
|
|
|
2860
|
+ NSLayoutConstraint.activate([
|
|
|
2861
|
+ shell.heightAnchor.constraint(equalToConstant: 34),
|
|
|
2862
|
+ picker.leadingAnchor.constraint(equalTo: shell.leadingAnchor, constant: 8),
|
|
|
2863
|
+ picker.trailingAnchor.constraint(equalTo: shell.trailingAnchor, constant: -8),
|
|
|
2864
|
+ picker.centerYAnchor.constraint(equalTo: shell.centerYAnchor)
|
|
|
2865
|
+ ])
|
|
|
2866
|
+
|
|
|
2867
|
+ return (shell, picker)
|
|
2830
|
2868
|
}
|
|
2831
|
2869
|
|
|
2832
|
2870
|
private func makeSchedulePagePillButton(title: String, action: Selector) -> NSButton {
|
|
|
@@ -4477,8 +4515,11 @@ private extension ViewController {
|
|
4477
|
4515
|
let isCustom = schedulePageFilter == .customRange
|
|
4478
|
4516
|
schedulePageFromDatePicker?.isEnabled = isCustom
|
|
4479
|
4517
|
schedulePageToDatePicker?.isEnabled = isCustom
|
|
4480
|
|
- schedulePageFromDatePicker?.alphaValue = isCustom ? 1.0 : 0.65
|
|
4481
|
|
- schedulePageToDatePicker?.alphaValue = isCustom ? 1.0 : 0.65
|
|
|
4518
|
+ let dim: CGFloat = isCustom ? 1.0 : 0.65
|
|
|
4519
|
+ schedulePageFromDatePicker?.alphaValue = 1
|
|
|
4520
|
+ schedulePageToDatePicker?.alphaValue = 1
|
|
|
4521
|
+ schedulePageFromDatePicker?.superview?.alphaValue = dim
|
|
|
4522
|
+ schedulePageToDatePicker?.superview?.alphaValue = dim
|
|
4482
|
4523
|
}
|
|
4483
|
4524
|
|
|
4484
|
4525
|
private func schedulePageHasValidCustomRange() -> Bool {
|