Skip to content

Commit 7514d17

Browse files
committed
Merge branch 'release/1.2.5'
2 parents 0eac1b4 + 625d7e8 commit 7514d17

File tree

11 files changed

+339
-86
lines changed

11 files changed

+339
-86
lines changed

Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ SPEC CHECKSUMS:
1313

1414
PODFILE CHECKSUM: 10e6f5005867dbb3964c6d40690aff5abd64540b
1515

16-
COCOAPODS: 1.9.1
16+
COCOAPODS: 1.9.3

Song Rating.xcodeproj/project.pbxproj

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
DB9D9B6B2363FF45008C53C3 /* NotificationName.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D9B6A2363FF45008C53C3 /* NotificationName.swift */; };
5252
DB9D9B6C2363FF45008C53C3 /* NotificationName.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D9B6A2363FF45008C53C3 /* NotificationName.swift */; };
5353
DB9D9B6F2364288E008C53C3 /* UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D9B6E2364288E008C53C3 /* UserDefaults.swift */; };
54+
DBD6A936250DA48E002C1B6C /* NSBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBD6A935250DA48E002C1B6C /* NSBox.swift */; };
55+
DBD6A938250E0A1C002C1B6C /* NSImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBD6A937250E0A1C002C1B6C /* NSImage.swift */; };
5456
FE421476F34E641428B030E9 /* Pods_Song_Rating.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DFF0EB36C01E667D4778CCC /* Pods_Song_Rating.framework */; };
5557
/* End PBXBuildFile section */
5658

@@ -136,6 +138,8 @@
136138
DB9D9B682363FD2E008C53C3 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; };
137139
DB9D9B6A2363FF45008C53C3 /* NotificationName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationName.swift; sourceTree = "<group>"; };
138140
DB9D9B6E2364288E008C53C3 /* UserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaults.swift; sourceTree = "<group>"; };
141+
DBD6A935250DA48E002C1B6C /* NSBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSBox.swift; sourceTree = "<group>"; };
142+
DBD6A937250E0A1C002C1B6C /* NSImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSImage.swift; sourceTree = "<group>"; };
139143
/* End PBXFileReference section */
140144

141145
/* Begin PBXFrameworksBuildPhase section */
@@ -346,6 +350,8 @@
346350
children = (
347351
DB9D9AEF235F7974008C53C3 /* DispatchQueue.swift */,
348352
DB9D9B6E2364288E008C53C3 /* UserDefaults.swift */,
353+
DBD6A935250DA48E002C1B6C /* NSBox.swift */,
354+
DBD6A937250E0A1C002C1B6C /* NSImage.swift */,
349355
);
350356
path = Extension;
351357
sourceTree = "<group>";
@@ -569,10 +575,12 @@
569575
DB89CA0022E37826003981F5 /* OSVersionHelper.swift in Sources */,
570576
DB424A45230D877900230C7E /* PlayerHistoryViewController.swift in Sources */,
571577
DB106CA622CA3EE700502D7C /* Stars.swift in Sources */,
578+
DBD6A938250E0A1C002C1B6C /* NSImage.swift in Sources */,
572579
DB2797732306F0EC00DDE3EB /* iTunesApplication.swift in Sources */,
573580
DB05F08A2354FC7700CE6DF9 /* PlayerControlView.swift in Sources */,
574581
DB424A3C230877F400230C7E /* PlayerViewController.swift in Sources */,
575582
DB95216A22CB186F007FCF40 /* WindowManager.swift in Sources */,
583+
DBD6A936250DA48E002C1B6C /* NSBox.swift in Sources */,
576584
DB05F0652353912500CE6DF9 /* PlayerInfoView.swift in Sources */,
577585
DB9D9B6B2363FF45008C53C3 /* NotificationName.swift in Sources */,
578586
DB95217222CB3E68007FCF40 /* PreferencesViewController.swift in Sources */,
@@ -768,15 +776,15 @@
768776
CODE_SIGN_IDENTITY = "Apple Development";
769777
CODE_SIGN_STYLE = Automatic;
770778
COMBINE_HIDPI_IMAGES = YES;
771-
CURRENT_PROJECT_VERSION = 9;
779+
CURRENT_PROJECT_VERSION = 10;
772780
DEVELOPMENT_TEAM = A8K92XFF77;
773781
ENABLE_HARDENED_RUNTIME = YES;
774782
INFOPLIST_FILE = "Song Rating/Info.plist";
775783
LD_RUNPATH_SEARCH_PATHS = (
776784
"$(inherited)",
777785
"@executable_path/../Frameworks",
778786
);
779-
MARKETING_VERSION = 1.2.4;
787+
MARKETING_VERSION = 1.2.5;
780788
PRODUCT_BUNDLE_IDENTIFIER = "com.mainasuk.Song-Rating";
781789
PRODUCT_NAME = "$(TARGET_NAME)";
782790
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -796,15 +804,15 @@
796804
CODE_SIGN_IDENTITY = "Apple Development";
797805
CODE_SIGN_STYLE = Automatic;
798806
COMBINE_HIDPI_IMAGES = YES;
799-
CURRENT_PROJECT_VERSION = 9;
807+
CURRENT_PROJECT_VERSION = 10;
800808
DEVELOPMENT_TEAM = A8K92XFF77;
801809
ENABLE_HARDENED_RUNTIME = YES;
802810
INFOPLIST_FILE = "Song Rating/Info.plist";
803811
LD_RUNPATH_SEARCH_PATHS = (
804812
"$(inherited)",
805813
"@executable_path/../Frameworks",
806814
);
807-
MARKETING_VERSION = 1.2.4;
815+
MARKETING_VERSION = 1.2.5;
808816
PRODUCT_BUNDLE_IDENTIFIER = "com.mainasuk.Song-Rating";
809817
PRODUCT_NAME = "$(TARGET_NAME)";
810818
PROVISIONING_PROFILE_SPECIFIER = "";

Song Rating.xcodeproj/xcshareddata/xcschemes/Song Rating - Debug Memory.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1150"
3+
LastUpgradeVersion = "1170"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

Song Rating.xcodeproj/xcshareddata/xcschemes/Song Rating.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1150"
3+
LastUpgradeVersion = "1170"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

Song Rating/AppDelegate.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,33 @@ extension AppDelegate {
8282
let ratingDownShortcut = MASShortcut(keyCode: kVK_ANSI_Comma, modifierFlags: .option)
8383
let ratingUpShortcut = MASShortcut(keyCode: kVK_ANSI_Period, modifierFlags: .option)
8484
let showOrClosePopoverShortcut = MASShortcut(keyCode: kVK_ANSI_Slash, modifierFlags: .option)
85+
let songRating5Shortcut = MASShortcut(keyCode: kVK_ANSI_5, modifierFlags: .option)
86+
let songRating4Shortcut = MASShortcut(keyCode: kVK_ANSI_4, modifierFlags: .option)
87+
let songRating3Shortcut = MASShortcut(keyCode: kVK_ANSI_3, modifierFlags: .option)
88+
let songRating2Shortcut = MASShortcut(keyCode: kVK_ANSI_2, modifierFlags: .option)
89+
let songRating1Shortcut = MASShortcut(keyCode: kVK_ANSI_1, modifierFlags: .option)
90+
let songRating0Shortcut = MASShortcut(keyCode: kVK_ANSI_Grave, modifierFlags: .option)
91+
8592
let ratingDownShortcutData = try NSKeyedArchiver.archivedData(withRootObject: ratingDownShortcut as Any, requiringSecureCoding: false)
8693
let ratingUpShortcutData = try NSKeyedArchiver.archivedData(withRootObject: ratingUpShortcut as Any, requiringSecureCoding: false)
8794
let showOrClosePopoverShortcutData = try NSKeyedArchiver.archivedData(withRootObject: showOrClosePopoverShortcut as Any, requiringSecureCoding: false)
95+
let songRating5ShortcutData = try NSKeyedArchiver.archivedData(withRootObject: songRating5Shortcut as Any, requiringSecureCoding: false)
96+
let songRating4ShortcutData = try NSKeyedArchiver.archivedData(withRootObject: songRating4Shortcut as Any, requiringSecureCoding: false)
97+
let songRating3ShortcutData = try NSKeyedArchiver.archivedData(withRootObject: songRating3Shortcut as Any, requiringSecureCoding: false)
98+
let songRating2ShortcutData = try NSKeyedArchiver.archivedData(withRootObject: songRating2Shortcut as Any, requiringSecureCoding: false)
99+
let songRating1ShortcutData = try NSKeyedArchiver.archivedData(withRootObject: songRating1Shortcut as Any, requiringSecureCoding: false)
100+
let songRating0ShortcutData = try NSKeyedArchiver.archivedData(withRootObject: songRating0Shortcut as Any, requiringSecureCoding: false)
101+
88102
UserDefaults.standard.register(defaults: [
89103
PreferencesViewController.ShortcutKey.songRatingDown.rawValue : ratingDownShortcutData,
90104
PreferencesViewController.ShortcutKey.songRatingUp.rawValue : ratingUpShortcutData,
91105
PreferencesViewController.ShortcutKey.showOrClosePopover.rawValue : showOrClosePopoverShortcutData,
106+
PreferencesViewController.ShortcutKey.songRating5.rawValue: songRating5ShortcutData,
107+
PreferencesViewController.ShortcutKey.songRating4.rawValue: songRating4ShortcutData,
108+
PreferencesViewController.ShortcutKey.songRating3.rawValue: songRating3ShortcutData,
109+
PreferencesViewController.ShortcutKey.songRating2.rawValue: songRating2ShortcutData,
110+
PreferencesViewController.ShortcutKey.songRating1.rawValue: songRating1ShortcutData,
111+
PreferencesViewController.ShortcutKey.songRating0.rawValue: songRating0ShortcutData,
92112
])
93113
} catch {
94114
os_log("%{public}s[%{public}ld], %{public}s: Default shortcut set fail", ((#file as NSString).lastPathComponent), #line, #function)

Song Rating/Controllers/PreferencesViewController.swift

Lines changed: 128 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ import MASShortcut
1111

1212
final 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

90162
extension 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

98201
extension 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
148257
import SwiftUI
149258

150259
@available(macOS 10.15.0, *)
151260
struct 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

Comments
 (0)