@@ -58,7 +58,24 @@ final class MenuBarRatingControl {
5858 let ratingControl = RatingControl ( rating: 0 )
5959 let menuBarIcon : MenuBarIcon
6060 let trackingAreaResponser = TrackingAreaResponder ( )
61-
61+
62+ private let clickGestureRecognizer : NSClickGestureRecognizer = {
63+ let gestureRecognizer = NSClickGestureRecognizer ( )
64+ return gestureRecognizer
65+ } ( )
66+ private let doubleClickGestureRecognizer : NSClickGestureRecognizer = {
67+ let gestureRecognizer = NSClickGestureRecognizer ( )
68+ gestureRecognizer. numberOfClicksRequired = 2
69+ return gestureRecognizer
70+ } ( )
71+ private let pressGestureRecognizer : NSPressGestureRecognizer = {
72+ let gestureRecognizer = NSPressGestureRecognizer ( )
73+ return gestureRecognizer
74+ } ( )
75+ private let panGestureRecognizer : NSPanGestureRecognizer = {
76+ let gestureRecognizer = NSPanGestureRecognizer ( )
77+ return gestureRecognizer
78+ } ( )
6279
6380 private( set) lazy var menuBarMenu : NSMenu = {
6481 let menu = NSMenu ( )
@@ -91,9 +108,9 @@ final class MenuBarRatingControl {
91108 }
92109 private( set) var playState : PlayInfo . PlayerState = . unknown {
93110 didSet {
94- // FIXME: close undetached popover when menu bar collapse
111+ // FIXME: close attached popover when menu bar collapse
95112 if playState == . unknown {
96- WindowManager . shared. undetachedPopover ? . close ( )
113+ WindowManager . shared. attachedPopover ? . close ( )
97114 }
98115 }
99116 }
@@ -111,10 +128,30 @@ final class MenuBarRatingControl {
111128 }
112129
113130 button. image = ratingControl. starsImage
114- button. sendAction ( on: [ . leftMouseUp , . rightMouseUp, . leftMouseDragged ] )
131+ button. sendAction ( on: [ . rightMouseUp] )
115132 button. action = #selector( MenuBarRatingControl . action ( _: ) )
116133 button. target = self
117134 button. setButtonType ( . momentaryChange)
135+
136+ // set fail rule
137+ doubleClickGestureRecognizer. shouldRequireFailure ( of: clickGestureRecognizer)
138+ panGestureRecognizer. shouldRequireFailure ( of: pressGestureRecognizer)
139+
140+ clickGestureRecognizer. action = #selector( MenuBarRatingControl . clickGestureRecognizerHandler ( _: ) )
141+ clickGestureRecognizer. target = self
142+ button. addGestureRecognizer ( clickGestureRecognizer)
143+
144+ doubleClickGestureRecognizer. action = #selector( MenuBarRatingControl . doubleClickGestureRecognizerHandler ( _: ) )
145+ doubleClickGestureRecognizer. target = self
146+ button. addGestureRecognizer ( doubleClickGestureRecognizer)
147+
148+ pressGestureRecognizer. action = #selector( MenuBarRatingControl . pressGestureRecognizerHandler ( _: ) )
149+ pressGestureRecognizer. target = self
150+ button. addGestureRecognizer ( pressGestureRecognizer)
151+
152+ panGestureRecognizer. action = #selector( MenuBarRatingControl . panGestureRecognizerHandler ( _: ) )
153+ panGestureRecognizer. target = self
154+ button. addGestureRecognizer ( panGestureRecognizer)
118155
119156 let trackingArea = NSTrackingArea ( rect: button. bounds, options: [ . activeAlways, . mouseEnteredAndExited, . mouseMoved] , owner: trackingAreaResponser, userInfo: nil )
120157 button. addTrackingArea ( trackingArea)
@@ -154,32 +191,74 @@ extension MenuBarRatingControl {
154191
155192extension MenuBarRatingControl {
156193
157- @objc func action( _ sender: NSButton ) {
194+ @objc private func action( _ sender: NSButton ) {
158195 guard let event = NSApp . currentEvent else {
159196 return
160197 }
161198 os_log ( " %{public}s[%{public}ld], %{public}s: menu bar button receive event %s " , ( ( #file as NSString ) . lastPathComponent) , #line, #function, event. debugDescription)
162199
163200 switch event. type {
164- case . leftMouseUp where isStop :
165- let position = NSPoint ( x: 0 , y: sender. bounds. height + 5 )
166- menuBarMenu. popUp ( positioning: nil , at: position, in: sender)
167-
168201 case . rightMouseUp where isStop:
169202 let position = sender. convert ( event. locationInWindow, to: nil )
170203 menuBarMenu. popUp ( positioning: nil , at: position, in: sender)
171204
172- case . leftMouseUp, . leftMouseDragged:
173- ratingControl. action ( from: sender, with: event)
174-
175205 case . rightMouseUp:
176206 WindowManager . shared. triggerPopover ( )
177207
178208 default :
179209 os_log ( " %{public}s[%{public}ld], %{public}s: no handler for event %s " , ( ( #file as NSString ) . lastPathComponent) , #line, #function, event. debugDescription)
180210 }
181211 }
212+
213+ @objc private func clickGestureRecognizerHandler( _ sender: NSClickGestureRecognizer ) {
214+ os_log ( " %{public}s[%{public}ld], %{public}s: %s " , ( ( #file as NSString ) . lastPathComponent) , #line, #function, sender. debugDescription)
215+ guard let button = statusItem. button else { return }
216+
217+ switch sender. state {
218+ case . ended:
219+ ratingControl. action ( from: button, by: sender, behavior: . full)
220+ default :
221+ break
222+ }
223+ }
224+
225+ @objc private func doubleClickGestureRecognizerHandler( _ sender: NSClickGestureRecognizer ) {
226+ os_log ( " %{public}s[%{public}ld], %{public}s: %s " , ( ( #file as NSString ) . lastPathComponent) , #line, #function, sender. debugDescription)
227+ guard let button = statusItem. button else { return }
228+
229+ switch sender. state {
230+ case . ended:
231+ ratingControl. action ( from: button, by: sender, behavior: UserDefaults . standard. allowHalfStar ? . half : . full)
232+ default :
233+ break
234+ }
235+ }
236+
237+ @objc private func pressGestureRecognizerHandler( _ sender: NSPressGestureRecognizer ) {
238+ os_log ( " %{public}s[%{public}ld], %{public}s: %s " , ( ( #file as NSString ) . lastPathComponent) , #line, #function, sender. debugDescription)
239+ guard let button = statusItem. button else { return }
240+
241+ switch sender. state {
242+ case . ended:
243+ ratingControl. action ( from: button, by: sender, behavior: . full)
244+ default :
245+ break
246+ }
247+ }
182248
249+
250+ @objc private func panGestureRecognizerHandler( _ sender: NSPanGestureRecognizer ) {
251+ os_log ( " %{public}s[%{public}ld], %{public}s: %s " , ( ( #file as NSString ) . lastPathComponent) , #line, #function, sender. debugDescription)
252+ guard let button = statusItem. button else { return }
253+
254+ switch sender. state {
255+ case . changed, . ended:
256+ ratingControl. action ( from: button, by: sender, behavior: UserDefaults . standard. allowHalfStar ? . both: . full)
257+ default :
258+ break
259+ }
260+ }
261+
183262}
184263
185264// MARK: - RatingControlDelegate
@@ -212,8 +291,8 @@ extension MenuBarRatingControl {
212291 guard !isStop else {
213292 return
214293 }
215-
216- ratingControl. update ( rating: ratingControl. rating + 20 )
294+ let ratingChange : Int = UserDefaults . standard . allowHalfStar ? 10 : 20
295+ ratingControl. update ( rating: ratingControl. rating + ratingChange )
217296 iTunesRadioStation. shared. setRating ( ratingControl. rating)
218297 }
219298
@@ -223,7 +302,8 @@ extension MenuBarRatingControl {
223302 return
224303 }
225304
226- ratingControl. update ( rating: ratingControl. rating - 20 )
305+ let ratingChange : Int = UserDefaults . standard. allowHalfStar ? 10 : 20
306+ ratingControl. update ( rating: ratingControl. rating - ratingChange)
227307 iTunesRadioStation. shared. setRating ( ratingControl. rating)
228308 }
229309
0 commit comments