Skip to content

Commit

Permalink
fix: Desaturate the selection color when the application looses focus (
Browse files Browse the repository at this point in the history
  • Loading branch information
jbmorley authored Mar 22, 2024
1 parent 7e1dd8a commit 9ef34bb
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
3 changes: 2 additions & 1 deletion Example/Example/Views/Cell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ struct Cell: View {

@Environment(\.isSelected) var isSelected
@Environment(\.highlightState) var highlightState
@Environment(\.selectionColor) var selectionColor

var item: Item
var isPainted: Bool

var strokeColor: Color {
return isSelected || highlightState == .forSelection ? Color.accentColor : Color.clear
return isSelected || highlightState == .forSelection ? selectionColor : Color.clear
}

var body: some View {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#if os(macOS)

import Carbon
import Combine
import SwiftUI

import SelectableCollectionViewMacResources
Expand Down Expand Up @@ -83,6 +84,7 @@ public class CollectionViewContainer<Element: Hashable, Content: View>: NSView,
private let scrollView: CustomScrollView
private let collectionView: InteractiveCollectionView
private var dataSource: DataSource? = nil
private var cancellables: Set<AnyCancellable> = []

var provider: ((Element) -> Content?)? = nil

Expand All @@ -105,7 +107,9 @@ public class CollectionViewContainer<Element: Hashable, Content: View>: NSView,
else {
return ShortcutItemView()
}
view.configure(AnyView(content), parentHasFocus: collectionView.isFirstResponder)
view.configure(AnyView(content),
parentHasFocus: collectionView.isFirstResponder,
parentIsKey: collectionView.window?.isKeyWindow ?? false)
view.element = item
return view
}
Expand All @@ -129,6 +133,18 @@ public class CollectionViewContainer<Element: Hashable, Content: View>: NSView,

collectionView.isSelectable = true
collectionView.allowsMultipleSelection = true

// Observe application activity notifications to allow us to update the selection color.
let notificationCenter = NotificationCenter.default
notificationCenter
.publisher(for: NSApplication.didBecomeActiveNotification)
.combineLatest(notificationCenter
.publisher(for: NSApplication.didResignActiveNotification))
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
self?.updateSelection()
}
.store(in: &cancellables)
}

required init?(coder: NSCoder) {
Expand All @@ -150,7 +166,9 @@ public class CollectionViewContainer<Element: Hashable, Content: View>: NSView,
continue
}
let content = self.delegate?.collectionViewContainer(self, contentForElement: element)
item.configure(AnyView(content), parentHasFocus: collectionView.isFirstResponder)
item.configure(AnyView(content),
parentHasFocus: collectionView.isFirstResponder,
parentIsKey: collectionView.window?.isKeyWindow ?? false)
}

// Update the selection
Expand Down
9 changes: 6 additions & 3 deletions Sources/SelectableCollectionView/Views/ShortcutItemView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class ShortcutItemView: NSCollectionViewItem {
}

private var parentHasFocus: Bool = false
private var parentIsKey: Bool = false

override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nil, bundle: Resources.bundle)
Expand All @@ -63,10 +64,11 @@ class ShortcutItemView: NSCollectionViewItem {
}

private func host(_ content: AnyView) {

let modifiedContent = AnyView(content
.environment(\.isSelected, isSelected)
.environment(\.highlightState, .init(highlightState))
.environment(\.selectionColor, parentHasFocus ? Color(nsColor: .selectedContentBackgroundColor) : Color(nsColor: .unemphasizedSelectedContentBackgroundColor)))
.environment(\.selectionColor, parentHasFocus && parentIsKey ? Color(nsColor: .selectedContentBackgroundColor) : Color(nsColor: .unemphasizedSelectedContentBackgroundColor)))
if let hostingView = hostingView {
hostingView.rootView = modifiedContent
} else {
Expand All @@ -81,14 +83,15 @@ class ShortcutItemView: NSCollectionViewItem {
#warning("TODO: Not sure if this is necessary")
override func prepareForReuse() {
super.prepareForReuse()
configure(AnyView(EmptyView()), parentHasFocus: false)
configure(AnyView(EmptyView()), parentHasFocus: false, parentIsKey: false)
}

#warning("TODO: Called by the data source")
#warning("TODO: This should take an item")
func configure(_ content: AnyView, parentHasFocus: Bool) {
func configure(_ content: AnyView, parentHasFocus: Bool, parentIsKey: Bool) {
self.content = content
self.parentHasFocus = parentHasFocus
self.parentIsKey = parentIsKey
host(content)
}

Expand Down

0 comments on commit 9ef34bb

Please sign in to comment.