mirror of
https://github.com/danbee/persephone
synced 2025-03-04 08:39:11 +00:00
Draw separator lines on the song list table
This commit is contained in:
parent
31b764905a
commit
2bac18187c
@ -56,6 +56,7 @@
|
||||
E450AD9522262DF10091BED3 /* CoverArtQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = E450AD9422262DF10091BED3 /* CoverArtQueue.swift */; };
|
||||
E450AD98222633920091BED3 /* Alamofire.framework.dSYM in Resources */ = {isa = PBXBuildFile; fileRef = E450AD96222633920091BED3 /* Alamofire.framework.dSYM */; };
|
||||
E450ADA12229E7C90091BED3 /* PMKFoundation.framework.dSYM in Resources */ = {isa = PBXBuildFile; fileRef = E450AD9F2229E7C90091BED3 /* PMKFoundation.framework.dSYM */; };
|
||||
E45878382296173C00586A1C /* AlbumDetailSongRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E45878372296173C00586A1C /* AlbumDetailSongRowView.swift */; };
|
||||
E45962C62241A78500FC1A1E /* MPDCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = E45962C52241A78500FC1A1E /* MPDCommand.swift */; };
|
||||
E45E4FDA22515D87004B537F /* CHANGELOG.md in Resources */ = {isa = PBXBuildFile; fileRef = E45E4FD722515D87004B537F /* CHANGELOG.md */; };
|
||||
E45E4FDB22515D87004B537F /* Brewfile in Resources */ = {isa = PBXBuildFile; fileRef = E45E4FD822515D87004B537F /* Brewfile */; };
|
||||
@ -70,6 +71,7 @@
|
||||
E47E2FDD2220A6D100F747E6 /* Time.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47E2FDC2220A6D100F747E6 /* Time.swift */; };
|
||||
E47E2FE52220AA0700F747E6 /* AlbumViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47E2FE42220AA0700F747E6 /* AlbumViewLayout.swift */; };
|
||||
E4928E0B2218D62A001D4BEA /* CGColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4928E0A2218D62A001D4BEA /* CGColor.swift */; };
|
||||
E4A3A6A122A457B600EA2C40 /* AlbumDetailSongListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A3A6A022A457B600EA2C40 /* AlbumDetailSongListView.swift */; };
|
||||
E4A642DA22090CBE00067D21 /* MPDStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A642D922090CBE00067D21 /* MPDStatus.swift */; };
|
||||
E4A83BEF2221F8CF0098FED6 /* CoverArtPrefsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A83BEE2221F8CF0098FED6 /* CoverArtPrefsController.swift */; };
|
||||
E4A83BF12221FAA00098FED6 /* PreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A83BF02221FAA00098FED6 /* PreferencesViewController.swift */; };
|
||||
@ -270,6 +272,7 @@
|
||||
E450AD9E2229B9BC0091BED3 /* PersephoneBridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PersephoneBridgingHeader.h; sourceTree = "<group>"; };
|
||||
E450AD9F2229E7C90091BED3 /* PMKFoundation.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = PMKFoundation.framework.dSYM; path = Carthage/Build/Mac/PMKFoundation.framework.dSYM; sourceTree = "<group>"; };
|
||||
E450ADA02229E7C90091BED3 /* PMKFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PMKFoundation.framework; path = Carthage/Build/Mac/PMKFoundation.framework; sourceTree = "<group>"; };
|
||||
E45878372296173C00586A1C /* AlbumDetailSongRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDetailSongRowView.swift; sourceTree = "<group>"; };
|
||||
E45962C52241A78500FC1A1E /* MPDCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDCommand.swift; sourceTree = "<group>"; };
|
||||
E45E4FD722515D87004B537F /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = SOURCE_ROOT; };
|
||||
E45E4FD822515D87004B537F /* Brewfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Brewfile; sourceTree = SOURCE_ROOT; };
|
||||
@ -285,6 +288,7 @@
|
||||
E47E2FDC2220A6D100F747E6 /* Time.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Time.swift; sourceTree = "<group>"; };
|
||||
E47E2FE42220AA0700F747E6 /* AlbumViewLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlbumViewLayout.swift; sourceTree = "<group>"; };
|
||||
E4928E0A2218D62A001D4BEA /* CGColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGColor.swift; sourceTree = "<group>"; };
|
||||
E4A3A6A022A457B600EA2C40 /* AlbumDetailSongListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDetailSongListView.swift; sourceTree = "<group>"; };
|
||||
E4A642D922090CBE00067D21 /* MPDStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDStatus.swift; sourceTree = "<group>"; };
|
||||
E4A83BEE2221F8CF0098FED6 /* CoverArtPrefsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoverArtPrefsController.swift; sourceTree = "<group>"; };
|
||||
E4A83BF02221FAA00098FED6 /* PreferencesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesViewController.swift; sourceTree = "<group>"; };
|
||||
@ -464,6 +468,8 @@
|
||||
E47E2FD222205D2500F747E6 /* MainWindow.swift */,
|
||||
E4B11BB7227538FA0075461B /* CurrentCoverArtView.swift */,
|
||||
E423563F228623D2001216D6 /* QueueSongTitleView.swift */,
|
||||
E45878372296173C00586A1C /* AlbumDetailSongRowView.swift */,
|
||||
E4A3A6A022A457B600EA2C40 /* AlbumDetailSongListView.swift */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
@ -970,10 +976,12 @@
|
||||
E41E530E223EF4CF00173814 /* CoverArtService+Caching.swift in Sources */,
|
||||
E4E8CC922204F4B80024217A /* QueueViewController.swift in Sources */,
|
||||
E440519C227BAF2E0090CD6F /* UIActions.swift in Sources */,
|
||||
E45878382296173C00586A1C /* AlbumDetailSongRowView.swift in Sources */,
|
||||
E41E5312223EF74A00173814 /* CoverArtService+Filesystem.swift in Sources */,
|
||||
E41E5301223BF99300173814 /* MPDClient+Queue.swift in Sources */,
|
||||
E4EB237B220F7CF1008C70C0 /* MPDAlbum.swift in Sources */,
|
||||
E41E5303223BF9C300173814 /* MPDClient+Idle.swift in Sources */,
|
||||
E4A3A6A122A457B600EA2C40 /* AlbumDetailSongListView.swift in Sources */,
|
||||
E4B11B53226928F20075461B /* AppState.swift in Sources */,
|
||||
E435E3E4221CD75D00184CFC /* NSImage.swift in Sources */,
|
||||
E440519A22787CF60090CD6F /* MPDReducer.swift in Sources */,
|
||||
|
||||
@ -22,8 +22,8 @@ class AlbumDetailView: NSViewController {
|
||||
|
||||
albumTracksView.dataSource = dataSource
|
||||
albumTracksView.delegate = self
|
||||
albumTracksView.intercellSpacing = CGSize(width: 0, height: 13)
|
||||
albumTracksView.gridStyleMask = .solidHorizontalGridLineMask
|
||||
albumTracksView.intercellSpacing = CGSize(width: 0, height: 18)
|
||||
albumTracksView.floatsGroupRows = false
|
||||
|
||||
albumCoverView.wantsLayer = true
|
||||
albumCoverView.layer?.cornerRadius = 5
|
||||
@ -47,9 +47,11 @@ class AlbumDetailView: NSViewController {
|
||||
|
||||
func getAlbumSongs(for album: Album) {
|
||||
App.mpdClient.getAlbumSongs(for: album.mpdAlbum) { (mpdSongs: [MPDClient.MPDSong]) in
|
||||
self.dataSource.albumTracks = mpdSongs.map {
|
||||
return Song(mpdSong: $0)
|
||||
}
|
||||
self.dataSource.setAlbumSongs(
|
||||
mpdSongs.map { Song(mpdSong: $0) }
|
||||
)
|
||||
|
||||
self.getBigCoverArt(song: self.dataSource.albumSongs.first!.song ?? self.dataSource.albumSongs[1].song!)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.albumTracksView.reloadData()
|
||||
@ -57,6 +59,20 @@ class AlbumDetailView: NSViewController {
|
||||
}
|
||||
}
|
||||
|
||||
func getBigCoverArt(song: Song) {
|
||||
let coverArtService = CoverArtService(song: song)
|
||||
|
||||
coverArtService.fetchBigCoverArt()
|
||||
.done() { image in
|
||||
DispatchQueue.main.async {
|
||||
if let image = image {
|
||||
self.albumCoverView.image = image
|
||||
}
|
||||
}
|
||||
}
|
||||
.cauterize()
|
||||
}
|
||||
|
||||
func setAppearance() {
|
||||
if #available(OSX 10.14, *) {
|
||||
let darkMode = NSApp.effectiveAppearance.bestMatch(from:
|
||||
@ -75,26 +91,45 @@ class AlbumDetailView: NSViewController {
|
||||
|
||||
extension AlbumDetailView: NSTableViewDelegate {
|
||||
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
|
||||
let song = dataSource.albumTracks[row]
|
||||
|
||||
switch tableColumn?.identifier.rawValue {
|
||||
case "trackNumberColumn":
|
||||
return cellForTrackNumber(tableView, with: song)
|
||||
case "trackTitleColumn":
|
||||
return cellForSongTitle(tableView, with: song)
|
||||
case "trackDurationColumn":
|
||||
return cellForSongDuration(tableView, with: song)
|
||||
default:
|
||||
return nil
|
||||
if let song = dataSource.albumSongs[row].song {
|
||||
switch tableColumn?.identifier.rawValue {
|
||||
case "trackNumberColumn":
|
||||
return cellForTrackNumber(tableView, with: song)
|
||||
case "trackTitleColumn":
|
||||
return cellForSongTitle(tableView, with: song)
|
||||
case "trackDurationColumn":
|
||||
return cellForSongDuration(tableView, with: song)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
} else if let disc = dataSource.albumSongs[row].disc {
|
||||
return cellForDiscNumber(tableView, with: disc)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func tableView(_ tableView: NSTableView, isGroupRow row: Int) -> Bool {
|
||||
return dataSource.albumSongs[row].disc != nil
|
||||
}
|
||||
|
||||
func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
|
||||
let view = NSTableRowView()
|
||||
let view = AlbumDetailSongRowView()
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
func cellForDiscNumber(_ tableView: NSTableView, with disc: String) -> NSView {
|
||||
let cellView = tableView.makeView(
|
||||
withIdentifier: .discNumber,
|
||||
owner: self
|
||||
) as! NSTableCellView
|
||||
|
||||
cellView.textField?.stringValue = "Disc \(disc)"
|
||||
|
||||
return cellView
|
||||
}
|
||||
|
||||
func cellForTrackNumber(_ tableView: NSTableView, with song: Song) -> NSView {
|
||||
let cellView = tableView.makeView(
|
||||
withIdentifier: .trackNumber,
|
||||
|
||||
@ -9,9 +9,37 @@
|
||||
import AppKit
|
||||
|
||||
class AlbumTracksDataSource: NSObject, NSTableViewDataSource {
|
||||
var albumTracks: [Song] = []
|
||||
struct AlbumSongItem {
|
||||
let disc: String?
|
||||
let song: Song?
|
||||
|
||||
init(song: Song) {
|
||||
self.disc = nil
|
||||
self.song = song
|
||||
}
|
||||
|
||||
init(disc: String) {
|
||||
self.disc = disc
|
||||
self.song = nil
|
||||
}
|
||||
}
|
||||
|
||||
var albumSongs: [AlbumSongItem] = []
|
||||
|
||||
func setAlbumSongs(_ songs: [Song]) {
|
||||
var disc: String? = ""
|
||||
|
||||
songs.forEach { song in
|
||||
if song.disc != disc {
|
||||
disc = song.disc
|
||||
albumSongs.append(AlbumSongItem(disc: song.disc))
|
||||
}
|
||||
|
||||
albumSongs.append(AlbumSongItem(song: song))
|
||||
}
|
||||
}
|
||||
|
||||
func numberOfRows(in tableView: NSTableView) -> Int {
|
||||
return albumTracks.count
|
||||
return albumSongs.count
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ extension NSUserInterfaceItemIdentifier {
|
||||
|
||||
static let albumViewItem = NSUserInterfaceItemIdentifier("AlbumViewItem")
|
||||
|
||||
static let discNumber = NSUserInterfaceItemIdentifier("discNumberCell")
|
||||
static let trackNumber = NSUserInterfaceItemIdentifier("trackNumberCell")
|
||||
static let songTitle = NSUserInterfaceItemIdentifier("songTitleCell")
|
||||
static let songDuration = NSUserInterfaceItemIdentifier("songDurationCell")
|
||||
|
||||
@ -11,6 +11,10 @@ import Foundation
|
||||
struct Song {
|
||||
var mpdSong: MPDClient.MPDSong
|
||||
|
||||
var disc: String {
|
||||
return mpdSong.getTag(.disc)
|
||||
}
|
||||
|
||||
var trackNumber: String {
|
||||
return mpdSong.getTag(.track)
|
||||
}
|
||||
|
||||
@ -22,9 +22,9 @@
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="m2v-pR-e9v">
|
||||
<rect key="frame" x="357" y="512" width="448" height="29"/>
|
||||
<rect key="frame" x="357" y="507" width="448" height="29"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="444" id="64T-pe-ww2"/>
|
||||
<constraint firstAttribute="width" constant="444" id="erC-QS-9hc"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" title="Album Title" id="URb-mh-vZz">
|
||||
<font key="font" metaFont="systemSemibold" size="24"/>
|
||||
@ -33,7 +33,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4Jx-I5-Nkv">
|
||||
<rect key="frame" x="357" y="485" width="448" height="19"/>
|
||||
<rect key="frame" x="357" y="480" width="448" height="19"/>
|
||||
<textFieldCell key="cell" title="Artist Name" id="ztJ-4E-qvI">
|
||||
<font key="font" metaFont="system" size="16"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
@ -41,29 +41,33 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="FWd-vZ-5CT">
|
||||
<rect key="frame" x="31" y="241" width="300" height="300"/>
|
||||
<rect key="frame" x="31" y="236" width="300" height="300"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="300" id="WkH-QY-IM1"/>
|
||||
<constraint firstAttribute="width" secondItem="FWd-vZ-5CT" secondAttribute="height" multiplier="1:1" id="m2r-ee-czT"/>
|
||||
<constraint firstAttribute="height" constant="300" id="69o-NQ-qL7"/>
|
||||
<constraint firstAttribute="width" constant="300" id="8XY-bQ-C7X"/>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="300" id="cyo-wr-hV8"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="defaultCoverArt" id="scE-kj-gex"/>
|
||||
</imageView>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jMU-bv-TNF">
|
||||
<rect key="frame" x="31" y="182" width="119" height="35"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<button verticalHuggingPriority="750" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jMU-bv-TNF">
|
||||
<rect key="frame" x="31" y="177" width="119" height="35"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="33" id="2uQ-mC-4QY"/>
|
||||
<constraint firstAttribute="width" constant="119" id="h2n-ZB-Ufr"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="smallSquare" title="Play Album" bezelStyle="smallSquare" image="playButton" imagePosition="left" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Rtg-Zd-JYc">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BOb-Lr-10M">
|
||||
<rect key="frame" x="359" y="30" width="444" height="426"/>
|
||||
<rect key="frame" x="359" y="33" width="444" height="418"/>
|
||||
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="9QN-UB-b4l">
|
||||
<rect key="frame" x="0.0" y="0.0" width="444" height="426"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="444" height="418"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="ehr-qh-87Q">
|
||||
<rect key="frame" x="0.0" y="0.0" width="444" height="426"/>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="ehr-qh-87Q" customClass="AlbumDetailSongListView" customModule="Persephone" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="444" height="418"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" red="0.11764705882352941" green="0.11764705882352941" blue="0.11764705882352941" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
@ -104,6 +108,30 @@
|
||||
<outlet property="textField" destination="6eU-Jx-HDR" id="DWy-vj-9Eq"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
<tableCellView identifier="discNumberCell" id="MHh-8c-iyL">
|
||||
<rect key="frame" x="1" y="20" width="40" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="nwx-zY-r5o">
|
||||
<rect key="frame" x="0.0" y="0.0" width="441" height="17"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="437" id="irN-AG-Pcj"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Disc 1" id="jya-2a-lit">
|
||||
<font key="font" metaFont="systemBold"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="nwx-zY-r5o" firstAttribute="centerY" secondItem="MHh-8c-iyL" secondAttribute="centerY" id="IOV-5t-KTN"/>
|
||||
<constraint firstItem="nwx-zY-r5o" firstAttribute="leading" secondItem="MHh-8c-iyL" secondAttribute="leading" constant="2" id="nw0-ya-Pwt"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="textField" destination="nwx-zY-r5o" id="NFl-7o-wmK"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
<tableColumn identifier="trackTitleColumn" width="353" minWidth="40" maxWidth="1000" id="7yp-QQ-EzC">
|
||||
@ -196,17 +224,20 @@
|
||||
</scrollView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="BOb-Lr-10M" secondAttribute="bottom" constant="30" id="AaR-Nq-vZD"/>
|
||||
<constraint firstItem="4Jx-I5-Nkv" firstAttribute="top" secondItem="m2v-pR-e9v" secondAttribute="bottom" constant="8" symbolic="YES" id="P10-cj-Iaz"/>
|
||||
<constraint firstItem="m2v-pR-e9v" firstAttribute="leading" secondItem="4Jx-I5-Nkv" secondAttribute="leading" id="PVJ-Rk-9K5"/>
|
||||
<constraint firstItem="m2v-pR-e9v" firstAttribute="trailing" secondItem="4Jx-I5-Nkv" secondAttribute="trailing" id="PlO-jD-clF"/>
|
||||
<constraint firstItem="FWd-vZ-5CT" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="31" id="Pyj-e4-N8r"/>
|
||||
<constraint firstItem="FWd-vZ-5CT" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="Yvv-MA-LPf"/>
|
||||
<constraint firstItem="m2v-pR-e9v" firstAttribute="leading" secondItem="BOb-Lr-10M" secondAttribute="leading" id="aLT-36-8oT"/>
|
||||
<constraint firstItem="m2v-pR-e9v" firstAttribute="trailing" secondItem="BOb-Lr-10M" secondAttribute="trailing" id="dpm-La-xDl"/>
|
||||
<constraint firstItem="BOb-Lr-10M" firstAttribute="top" secondItem="4Jx-I5-Nkv" secondAttribute="bottom" constant="29" id="f3Q-VP-2Y2"/>
|
||||
<constraint firstAttribute="trailing" secondItem="m2v-pR-e9v" secondAttribute="trailing" constant="20" symbolic="YES" id="sEh-fo-Kqa"/>
|
||||
<constraint firstItem="m2v-pR-e9v" firstAttribute="top" secondItem="FWd-vZ-5CT" secondAttribute="top" id="zLA-y0-JQ9"/>
|
||||
<constraint firstItem="FWd-vZ-5CT" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="31" id="694-aS-G4N"/>
|
||||
<constraint firstItem="jMU-bv-TNF" firstAttribute="leading" secondItem="FWd-vZ-5CT" secondAttribute="leading" id="AwZ-M4-fep"/>
|
||||
<constraint firstItem="BOb-Lr-10M" firstAttribute="leading" secondItem="4Jx-I5-Nkv" secondAttribute="leading" id="GEK-R3-Sw6"/>
|
||||
<constraint firstItem="BOb-Lr-10M" firstAttribute="top" secondItem="4Jx-I5-Nkv" secondAttribute="bottom" constant="29" id="K5g-Kd-iHK"/>
|
||||
<constraint firstAttribute="bottom" secondItem="BOb-Lr-10M" secondAttribute="bottom" constant="33" id="MZ6-81-2qe"/>
|
||||
<constraint firstItem="4Jx-I5-Nkv" firstAttribute="leading" secondItem="m2v-pR-e9v" secondAttribute="leading" id="NaJ-VT-uln"/>
|
||||
<constraint firstItem="FWd-vZ-5CT" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="25" id="QA9-xn-fzY"/>
|
||||
<constraint firstItem="m2v-pR-e9v" firstAttribute="top" secondItem="FWd-vZ-5CT" secondAttribute="top" id="bqi-HD-KZW"/>
|
||||
<constraint firstItem="jMU-bv-TNF" firstAttribute="top" secondItem="FWd-vZ-5CT" secondAttribute="bottom" constant="25" id="dd1-6b-TEN"/>
|
||||
<constraint firstItem="4Jx-I5-Nkv" firstAttribute="trailing" secondItem="m2v-pR-e9v" secondAttribute="trailing" id="dmh-TC-Ncr"/>
|
||||
<constraint firstItem="m2v-pR-e9v" firstAttribute="leading" secondItem="FWd-vZ-5CT" secondAttribute="trailing" constant="28" id="icS-vq-PkK"/>
|
||||
<constraint firstItem="4Jx-I5-Nkv" firstAttribute="top" secondItem="m2v-pR-e9v" secondAttribute="bottom" constant="8" symbolic="YES" id="nTZ-Ew-sDQ"/>
|
||||
<constraint firstAttribute="trailing" secondItem="m2v-pR-e9v" secondAttribute="trailing" constant="20" symbolic="YES" id="qyi-X9-6B9"/>
|
||||
<constraint firstItem="BOb-Lr-10M" firstAttribute="trailing" secondItem="4Jx-I5-Nkv" secondAttribute="trailing" id="sPx-cY-MeX"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="262.5" y="117.5"/>
|
||||
</customView>
|
||||
|
||||
@ -569,8 +569,8 @@
|
||||
<rect key="frame" x="1" y="1" width="200" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xgd-Cz-np3">
|
||||
<rect key="frame" x="0.0" y="2" width="447" height="14"/>
|
||||
<textField verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xgd-Cz-np3">
|
||||
<rect key="frame" x="0.0" y="2" width="322" height="14"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="443" id="mkA-ng-q8a"/>
|
||||
</constraints>
|
||||
|
||||
13
Persephone/Views/AlbumDetailSongListView.swift
Normal file
13
Persephone/Views/AlbumDetailSongListView.swift
Normal file
@ -0,0 +1,13 @@
|
||||
//
|
||||
// AlbumDetailSongListView.swift
|
||||
// Persephone
|
||||
//
|
||||
// Created by Daniel Barber on 2019/6/02.
|
||||
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
|
||||
class AlbumDetailSongListView: NSTableView {
|
||||
override func drawGrid(inClipRect clipRect: NSRect) { }
|
||||
}
|
||||
27
Persephone/Views/AlbumDetailSongRowView.swift
Normal file
27
Persephone/Views/AlbumDetailSongRowView.swift
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// AlbumDetailSongRowView.swift
|
||||
// Persephone
|
||||
//
|
||||
// Created by Daniel Barber on 2019/5/22.
|
||||
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
|
||||
class AlbumDetailSongRowView: NSTableRowView {
|
||||
override func drawBackground(in dirtyRect: NSRect) {
|
||||
let borderPath = CGMutablePath()
|
||||
let startingPoint = CGPoint(x: dirtyRect.origin.x, y: dirtyRect.height)
|
||||
let endingPoint = CGPoint(x: dirtyRect.width, y: dirtyRect.height)
|
||||
|
||||
borderPath.move(to: startingPoint)
|
||||
borderPath.addLine(to: endingPoint)
|
||||
|
||||
let shapeLayer = CAShapeLayer()
|
||||
self.layer?.addSublayer(shapeLayer)
|
||||
|
||||
shapeLayer.path = borderPath
|
||||
shapeLayer.strokeColor = NSColor.secondaryLabelColor.cgColor
|
||||
shapeLayer.lineWidth = 1
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user