@@ -11,6 +11,10 @@ import MASShortcut
1111
1212final class PreferencesViewController : NSViewController {
1313
14+ static var defaultTextFieldFontSize : CGFloat {
15+ return NSTextField ( labelWithString: " sample " ) . font!. pointSize
16+ }
17+
1418 lazy var StartupTextField : NSTextField = {
1519 return NSTextField ( labelWithString: " Startup: " )
1620 } ( )
@@ -20,6 +24,34 @@ final class PreferencesViewController: NSViewController {
2024 lazy var songRatingUpTextField : NSTextField = {
2125 return NSTextField ( labelWithString: " Song rating up: " )
2226 } ( )
27+ lazy var songRating5TextField : NSTextField = {
28+ let attributedString = PreferencesViewController . starsAttributedString ( count: 5 , fontSize: PreferencesViewController . defaultTextFieldFontSize)
29+ attributedString. append ( NSAttributedString ( string: " : " ) )
30+ return NSTextField ( labelWithAttributedString: attributedString)
31+ } ( )
32+ lazy var songRating4TextField : NSTextField = {
33+ let attributedString = PreferencesViewController . starsAttributedString ( count: 4 , fontSize: PreferencesViewController . defaultTextFieldFontSize)
34+ attributedString. append ( NSAttributedString ( string: " : " ) )
35+ return NSTextField ( labelWithAttributedString: attributedString)
36+ } ( )
37+ lazy var songRating3TextField : NSTextField = {
38+ let attributedString = PreferencesViewController . starsAttributedString ( count: 3 , fontSize: PreferencesViewController . defaultTextFieldFontSize)
39+ attributedString. append ( NSAttributedString ( string: " : " ) )
40+ return NSTextField ( labelWithAttributedString: attributedString)
41+ } ( )
42+ lazy var songRating2TextField : NSTextField = {
43+ let attributedString = PreferencesViewController . starsAttributedString ( count: 2 , fontSize: PreferencesViewController . defaultTextFieldFontSize)
44+ attributedString. append ( NSAttributedString ( string: " : " ) )
45+ return NSTextField ( labelWithAttributedString: attributedString)
46+ } ( )
47+ lazy var songRating1TextField : NSTextField = {
48+ let attributedString = PreferencesViewController . starsAttributedString ( count: 1 , fontSize: PreferencesViewController . defaultTextFieldFontSize)
49+ attributedString. append ( NSAttributedString ( string: " : " ) )
50+ return NSTextField ( labelWithAttributedString: attributedString)
51+ } ( )
52+ lazy var songRating0TextField : NSTextField = {
53+ return NSTextField ( labelWithString: " Remove stars: " )
54+ } ( )
2355 lazy var showOrClosePopoverTextField : NSTextField = {
2456 return NSTextField ( labelWithString: " Show/Close popover: " )
2557 } ( )
@@ -37,6 +69,36 @@ final class PreferencesViewController: NSViewController {
3769 shortcutView. associatedUserDefaultsKey = ShortcutKey . songRatingUp. rawValue
3870 return shortcutView
3971 } ( )
72+ let songRating5ShortcutView : MASShortcutView = {
73+ let shortcutView = MASShortcutView ( )
74+ shortcutView. associatedUserDefaultsKey = ShortcutKey . songRating5. rawValue
75+ return shortcutView
76+ } ( )
77+ let songRating4ShortcutView : MASShortcutView = {
78+ let shortcutView = MASShortcutView ( )
79+ shortcutView. associatedUserDefaultsKey = ShortcutKey . songRating4. rawValue
80+ return shortcutView
81+ } ( )
82+ let songRating3ShortcutView : MASShortcutView = {
83+ let shortcutView = MASShortcutView ( )
84+ shortcutView. associatedUserDefaultsKey = ShortcutKey . songRating3. rawValue
85+ return shortcutView
86+ } ( )
87+ let songRating2ShortcutView : MASShortcutView = {
88+ let shortcutView = MASShortcutView ( )
89+ shortcutView. associatedUserDefaultsKey = ShortcutKey . songRating2. rawValue
90+ return shortcutView
91+ } ( )
92+ let songRating1ShortcutView : MASShortcutView = {
93+ let shortcutView = MASShortcutView ( )
94+ shortcutView. associatedUserDefaultsKey = ShortcutKey . songRating1. rawValue
95+ return shortcutView
96+ } ( )
97+ let songRating0ShortcutView : MASShortcutView = {
98+ let shortcutView = MASShortcutView ( )
99+ shortcutView. associatedUserDefaultsKey = ShortcutKey . songRating0. rawValue
100+ return shortcutView
101+ } ( )
40102 let showOrClosePopoverShortcutView : MASShortcutView = {
41103 let shortcutView = MASShortcutView ( )
42104 shortcutView. associatedUserDefaultsKey = ShortcutKey . showOrClosePopover. rawValue
@@ -49,54 +111,95 @@ final class PreferencesViewController: NSViewController {
49111
50112 lazy var gridView : NSGridView = {
51113 let empty = NSGridCell . emptyContentView
52- let line = NSBox ( )
53- line. boxType = . separator
54114
55115 let gridView = NSGridView ( views: [
56116 [ StartupTextField, launchAtLoginCheckboxButton] ,
57- [ line ] ,
117+ [ NSBox . separatorLine ] ,
58118 [ songRatingDownTextField, songRatingDownShortcutView] ,
59119 [ songRatingUpTextField, songRatingUpShortcutView] ,
60120 [ showOrClosePopoverTextField, showOrClosePopoverShortcutView] ,
121+ [ NSBox . separatorLine] ,
122+ [ songRating0TextField, songRating0ShortcutView] ,
123+ [ songRating1TextField, songRating1ShortcutView] ,
124+ [ songRating2TextField, songRating2ShortcutView] ,
125+ [ songRating3TextField, songRating3ShortcutView] ,
126+ [ songRating4TextField, songRating4ShortcutView] ,
127+ [ songRating5TextField, songRating5ShortcutView] ,
61128 [ leadingPaddingView, trailingPaddingView]
62129 ] )
63-
130+
64131 gridView. row ( at: 0 ) . rowAlignment = . lastBaseline
65-
132+
66133 gridView. column ( at: 0 ) . xPlacement = . trailing
67134 gridView. column ( at: 1 ) . xPlacement = . leading
68135 gridView. rowSpacing = 8
69136
70- let lineRow = gridView. cell ( for: line) ? . row
71- lineRow? . mergeCells ( in: NSMakeRange ( 0 , 2 ) )
72- lineRow? . topPadding = 8
73- lineRow? . bottomPadding = 8
137+ let lines = gridView. subviews. filter { ( $0 as? NSBox ) ? . boxType == . separator }
138+ for line in lines {
139+ guard let lineRow = gridView. cell ( for: line) ? . row else {
140+ continue
141+ }
142+ lineRow. mergeCells ( in: NSMakeRange ( 0 , 2 ) )
143+ lineRow. topPadding = 8
144+ lineRow. bottomPadding = 8
145+ }
74146
75147 return gridView
76148 } ( )
77-
149+
78150 var launchAtLoginObservation : NSKeyValueObservation ?
79151
80152 override func loadView( ) {
81153 self . view = NSView ( )
82154 }
83-
155+
84156 deinit {
85157 launchAtLoginObservation? . invalidate ( )
86158 }
87-
159+
88160}
89161
90162extension PreferencesViewController {
91-
163+ private static func starsAttributedString( count: Int , fontSize: CGFloat ) -> NSMutableAttributedString {
164+ let font = NSFont . systemFont ( ofSize: fontSize)
165+ let stars = Stars (
166+ stars: Array ( repeating: Star ( size: CGSize ( width: fontSize, height: fontSize) , fill: true ) , count: count) ,
167+ spacing: 3
168+ )
169+ var image = stars. image
170+ image. isTemplate = true
171+ image = image. withTintColor ( . labelColor)
172+
173+ let attachment = NSTextAttachment ( )
174+ attachment. image = image
175+ // center vertical image
176+ attachment. bounds = CGRect (
177+ x: 0 ,
178+ y: ( font. capHeight - image. size. height) * 0.5 ,
179+ width: image. size. width,
180+ height: image. size. height
181+ )
182+
183+ let attributedString = NSMutableAttributedString ( )
184+ let attachmentAttributedString = NSAttributedString ( attachment: attachment)
185+ attributedString. append ( attachmentAttributedString)
186+ // not works. use tinted image workaround it
187+ attributedString. addAttribute ( . foregroundColor, value: NSColor . labelColor, range: NSRange ( location: 0 , length: attributedString. length) )
188+
189+ return attributedString
190+ }
191+ }
192+
193+ extension PreferencesViewController {
194+
92195 @objc private func launchAtLoginCheckboxButtonChanged( _ sender: NSButton ) {
93196 UserDefaults . standard. launchAtLogin = sender. state == . on
94197 }
95198
96199}
97200
98201extension PreferencesViewController {
99-
202+
100203 func setupWindow( ) {
101204 view. window? . styleMask. remove ( . resizable)
102205 }
@@ -120,14 +223,14 @@ extension PreferencesViewController {
120223 leadingPaddingView. widthAnchor. constraint ( equalTo: trailingPaddingView. widthAnchor, multiplier: 1.0 ) ,
121224 gridView. widthAnchor. constraint ( greaterThanOrEqualToConstant: 420 ) , // magic width
122225 ] )
123-
226+
124227 launchAtLoginCheckboxButton. target = self
125228 launchAtLoginCheckboxButton. action = #selector( PreferencesViewController . launchAtLoginCheckboxButtonChanged ( _: ) )
126229 launchAtLoginObservation = UserDefaults . standard. observe ( \. launchAtLogin, options: [ . initial, . new] ) { [ weak self] defaults, launchAtLogin in
127230 self ? . launchAtLoginCheckboxButton. state = defaults. launchAtLogin ? . on : . off
128231 }
129232 }
130-
233+
131234 override func viewDidAppear( ) {
132235 setupWindow ( )
133236 }
@@ -140,22 +243,28 @@ extension PreferencesViewController {
140243 case songRatingDown
141244 case songRatingUp
142245 case showOrClosePopover
246+ case songRating5
247+ case songRating4
248+ case songRating3
249+ case songRating2
250+ case songRating1
251+ case songRating0
143252 }
144-
253+
145254}
146255
147256#if canImport(SwiftUI) && DEBUG
148257import SwiftUI
149258
150259@available ( macOS 10 . 15 . 0 , * )
151260struct PreferencesViewController_Preview : PreviewProvider {
152-
261+
153262 static var previews : some View {
154263 NSViewControllerPreview {
155264 return PreferencesViewController ( )
156265 }
157266 }
158-
267+
159268}
160269
161270#endif
0 commit comments