From 14a73f10ade7a87b1b8cf1009e1e9b1ec1b32b17 Mon Sep 17 00:00:00 2001 From: xjbeta Date: Mon, 13 Aug 2018 14:20:42 +0800 Subject: [PATCH 01/25] Add error handle for decode url. --- iina+/Utils/Processes.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/iina+/Utils/Processes.swift b/iina+/Utils/Processes.swift index c05befea..317f680b 100644 --- a/iina+/Utils/Processes.swift +++ b/iina+/Utils/Processes.swift @@ -50,7 +50,8 @@ class Processes: NSObject { decodeTask = Process() let pipe = Pipe() - + let errorPipe = Pipe() + decodeTask?.standardError = errorPipe decodeTask?.standardOutput = pipe decodeTask?.launchPath = which(Preferences.shared.liveDecoder.rawValue).first ?? "" decodeTask?.arguments = ["--json", url] @@ -74,6 +75,11 @@ class Processes: NSObject { Logger.log("JSON string: \(str)") } } + + let errorData = errorPipe.fileHandleForReading.readDataToEndOfFile() + if let str = String(data: errorData, encoding: .utf8) { + Logger.log("Decode url error info: \(str)") + } } } From 93a9773331047e14119814995a36dc323c49ec30 Mon Sep 17 00:00:00 2001 From: xjbeta Date: Mon, 13 Aug 2018 14:37:30 +0800 Subject: [PATCH 02/25] Add decode url log. --- iina+/Utils/Processes.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iina+/Utils/Processes.swift b/iina+/Utils/Processes.swift index 317f680b..0e2138c0 100644 --- a/iina+/Utils/Processes.swift +++ b/iina+/Utils/Processes.swift @@ -57,6 +57,8 @@ class Processes: NSObject { decodeTask?.arguments = ["--json", url] decodeTask?.launch() + Logger.log(url) + decodeTask?.terminationHandler = { _ in guard self.decodeTask?.terminationReason != .uncaughtSignal else { return From 0732df93f38e6a39a183f431e00a2382625150fe Mon Sep 17 00:00:00 2001 From: xjbeta Date: Mon, 13 Aug 2018 14:39:59 +0800 Subject: [PATCH 03/25] Fix date for douyu cookies. --- iina+/Utils/Processes.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/iina+/Utils/Processes.swift b/iina+/Utils/Processes.swift index 0e2138c0..80485e4b 100644 --- a/iina+/Utils/Processes.swift +++ b/iina+/Utils/Processes.swift @@ -174,9 +174,10 @@ private extension Processes { str = str?.subString(from: "(", to: ")") let json = try JSONParser.JSONObjectWithData(str?.data(using: .utf8) ?? Data()) let didStr: String = try json.value(for: "data.did") + let date = Int(Date().timeIntervalSince1970) cookiesString = """ - ..douyu.com TRUE / FALSE 1535865698 dy_did \(didStr) - .www.douyu.com TRUE / FALSE 1535865771 acf_did \(didStr) + ..douyu.com TRUE / FALSE \(date) dy_did \(didStr) + .www.douyu.com TRUE / FALSE \(date) acf_did \(didStr) """ } catch let error { Logger.log("DouYu cookies error: \(error)") From f79da42d2ccf311ee24f8a7cda2117c832b69ea6 Mon Sep 17 00:00:00 2001 From: xjbeta Date: Tue, 14 Aug 2018 10:24:33 +0800 Subject: [PATCH 04/25] Update to Xcode10 beta6. --- iina+/AppDelegate.swift | 14 +++++++------- iina+/Views/MainMenu.swift | 5 +++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/iina+/AppDelegate.swift b/iina+/AppDelegate.swift index 6e029072..510b5636 100644 --- a/iina+/AppDelegate.swift +++ b/iina+/AppDelegate.swift @@ -75,9 +75,9 @@ class AppDelegate: NSObject, NSApplicationDelegate { // Performs the save action for the application, which is to send the save: message to the application's managed object context. Any encountered errors are presented to the user. let context = persistentContainer.viewContext - if !context.commitEditing() { - NSLog("\(NSStringFromClass(type(of: self))) unable to commit editing before saving") - } +// if !context.commitEditing() { +// NSLog("\(NSStringFromClass(type(of: self))) unable to commit editing before saving") +// } if context.hasChanges { do { try context.save() @@ -98,10 +98,10 @@ class AppDelegate: NSObject, NSApplicationDelegate { // Save changes in the application's managed object context before the application terminates. let context = persistentContainer.viewContext - if !context.commitEditing() { - NSLog("\(NSStringFromClass(type(of: self))) unable to commit editing to terminate") - return .terminateCancel - } +// if !context.commitEditing() { +// NSLog("\(NSStringFromClass(type(of: self))) unable to commit editing to terminate") +// return .terminateCancel +// } if !context.hasChanges { return .terminateNow diff --git a/iina+/Views/MainMenu.swift b/iina+/Views/MainMenu.swift index 8571632c..c815beda 100644 --- a/iina+/Views/MainMenu.swift +++ b/iina+/Views/MainMenu.swift @@ -8,8 +8,9 @@ import Cocoa -class MainMenu: NSObject { - override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool { +class MainMenu: NSObject, NSMenuItemValidation { + + func validateMenuItem(_ menuItem: NSMenuItem) -> Bool { if let window = NSApp.keyWindow, let appDelegate = NSApp.delegate as? AppDelegate, From feccc2caf0787a5b1e277635b6d154d027c9968e Mon Sep 17 00:00:00 2001 From: xjbeta Date: Wed, 15 Aug 2018 12:57:04 +0800 Subject: [PATCH 05/25] Add bilibili video preview. --- iina+.xcodeproj/project.pbxproj | 8 ++ iina+/Utils/Bilibili.swift | 99 +++++++++++++++++++ iina+/Views/Base.lproj/Main.storyboard | 96 +++++++++++------- .../Views/MainWindow/MainViewController.swift | 2 + .../BilibiliCardImageBoxView.swift | 87 ++++++++++++++++ .../BilibiliCardProgressView.swift | 31 ++++++ .../BilibiliCardTableCellView.swift | 1 + 7 files changed, 286 insertions(+), 38 deletions(-) create mode 100644 iina+/Views/MainWindow/TableViewCustomViews/BilibiliCardImageBoxView.swift create mode 100644 iina+/Views/MainWindow/TableViewCustomViews/BilibiliCardProgressView.swift diff --git a/iina+.xcodeproj/project.pbxproj b/iina+.xcodeproj/project.pbxproj index 10d408ac..50f621ec 100644 --- a/iina+.xcodeproj/project.pbxproj +++ b/iina+.xcodeproj/project.pbxproj @@ -28,6 +28,8 @@ 01260171211948BF00C9C639 /* PreferencesTabViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01260170211948BF00C9C639 /* PreferencesTabViewController.swift */; }; 012601742119FBF400C9C639 /* BilibiliCardTableCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012601732119FBF400C9C639 /* BilibiliCardTableCellView.swift */; }; 01260178211ABD3B00C9C639 /* VideoViewsFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01260177211ABD3B00C9C639 /* VideoViewsFormatter.swift */; }; + 0132B2E32123D05E001EB7DC /* BilibiliCardProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0132B2E22123D05E001EB7DC /* BilibiliCardProgressView.swift */; }; + 0132B2E52123D68D001EB7DC /* BilibiliCardImageBoxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0132B2E42123D68D001EB7DC /* BilibiliCardImageBoxView.swift */; }; 01398983210F273200B7042F /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01398982210F273200B7042F /* PreferencesView.swift */; }; 01398985210F27A600B7042F /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01398984210F27A600B7042F /* PreferencesWindowController.swift */; }; 01398987210F58E500B7042F /* MainWindowTableRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01398986210F58E500B7042F /* MainWindowTableRowView.swift */; }; @@ -101,6 +103,8 @@ 01260170211948BF00C9C639 /* PreferencesTabViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesTabViewController.swift; sourceTree = ""; }; 012601732119FBF400C9C639 /* BilibiliCardTableCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BilibiliCardTableCellView.swift; sourceTree = ""; }; 01260177211ABD3B00C9C639 /* VideoViewsFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoViewsFormatter.swift; sourceTree = ""; }; + 0132B2E22123D05E001EB7DC /* BilibiliCardProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BilibiliCardProgressView.swift; sourceTree = ""; }; + 0132B2E42123D68D001EB7DC /* BilibiliCardImageBoxView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BilibiliCardImageBoxView.swift; sourceTree = ""; }; 01398982210F273200B7042F /* PreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = ""; }; 01398984210F27A600B7042F /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = ""; }; 01398986210F58E500B7042F /* MainWindowTableRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainWindowTableRowView.swift; sourceTree = ""; }; @@ -164,6 +168,8 @@ 012601732119FBF400C9C639 /* BilibiliCardTableCellView.swift */, 0101012F211E987D002F0F7F /* SuggestionsTableCellView.swift */, 01010130211E987D002F0F7F /* WaitingTableCellView.swift */, + 0132B2E22123D05E001EB7DC /* BilibiliCardProgressView.swift */, + 0132B2E42123D68D001EB7DC /* BilibiliCardImageBoxView.swift */, ); path = TableViewCustomViews; sourceTree = ""; @@ -396,6 +402,7 @@ 014B447D210069FF00E7AA6A /* Bookmark.swift in Sources */, 01398987210F58E500B7042F /* MainWindowTableRowView.swift in Sources */, 01AEC8BC20EDFFBD001406E8 /* YouGetJSON.swift in Sources */, + 0132B2E52123D68D001EB7DC /* BilibiliCardImageBoxView.swift in Sources */, 01683DD9211869AE0016A886 /* BilibiliLoginViewController.swift in Sources */, 0196CB62212143D600BCD29E /* Logger.swift in Sources */, 010F0F1320FE1DD100F33553 /* Preferences.swift in Sources */, @@ -407,6 +414,7 @@ 01AEC8AB20EDFD01001406E8 /* AppDelegate.swift in Sources */, 01010137211EFA75002F0F7F /* SuggestionsTableView.swift in Sources */, 01E6A09C211AD62800C6EF98 /* VideoDurationFormatter.swift in Sources */, + 0132B2E32123D05E001EB7DC /* BilibiliCardProgressView.swift in Sources */, 0101012E211DE83B002F0F7F /* SidebarTableView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/iina+/Utils/Bilibili.swift b/iina+/Utils/Bilibili.swift index b6f414c0..3d89727f 100644 --- a/iina+/Utils/Bilibili.swift +++ b/iina+/Utils/Bilibili.swift @@ -51,6 +51,90 @@ enum BilibiliDynamicAction { case `init`, new, history } +struct BilibiliPvideo: Unmarshaling { + var images: [NSImage] = [] + var pImages: [NSImage] = [] + var xLen: Int = 0 + var yLen: Int = 0 + var xSize: Int = 0 + var ySize: Int = 0 + var imagesCount: Int = 0 + + enum CropImagesError: Error { + case zeroImagesCount + } + + init(object: MarshaledObject) throws { + let imageStrs: [String] = try object.value(for: "data.image") +// images = imageStrs.compactMap { str -> NSImage? in +// if let url = URL(string: str.replacingOccurrences(of: "http://", with: "https://")) { +// return NSImage(contentsOf: url) +// } else { +// return nil +// } +// } + let indexs: [Int] = try object.value(for: "data.index") + imagesCount = indexs.count + // limit image count for performance + if imagesCount > 100 { + imagesCount = 100 + } else if imagesCount == 0 { + throw CropImagesError.zeroImagesCount + } + if let iamgeStr = imageStrs.first, + let url = URL(string: iamgeStr.replacingOccurrences(of: "http://", with: "https://")), + let image = NSImage(contentsOf: url) { + images = [image] + } + + xLen = try object.value(for: "data.img_x_len") + yLen = try object.value(for: "data.img_y_len") + xSize = try object.value(for: "data.img_x_size") + ySize = try object.value(for: "data.img_y_size") + } + + mutating func cropImages() { + var pImages: [NSImage] = [] + var limitCount = 0 + images.forEach { image in + var xIndex = 0 + var yIndex = 0 + + if limitCount < imagesCount { + while yIndex < yLen { + while xIndex < xLen { + let rect = NSRect(x: xIndex * xSize, y: yIndex * ySize, width: xSize, height: ySize) + + if let croppedImage = crop(image, with: rect) { + pImages.append(croppedImage) + } + limitCount += 1 + if limitCount == imagesCount { + xIndex = 10 + yIndex = 10 + } + xIndex += 1 + if xIndex == xLen { + xIndex = 0 + yIndex += 1 + } + } + } + } + } + self.pImages = pImages + } + + func crop(_ image: NSImage, with rect: NSRect) -> NSImage? { + guard let croppedImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil)?.cropping(to: rect) else { + return nil + } + let reImage = NSImage(cgImage: croppedImage, size: rect.size) + return reImage + } +} + + class Bilibili: NSObject { func isLogin(_ isLoginBlock: ((Bool) -> Void)?, @@ -132,6 +216,21 @@ class Bilibili: NSObject { } } + func getPvideo(_ aid: Int, + _ block: @escaping ((BilibiliPvideo) -> Void), + _ error: @escaping ((HTTPErrorCallback) -> Void)) { + guard aid != 0 else { return } + HTTP.GET("https://api.bilibili.com/pvideo?aid=\(aid)") { response in + error { + let json: JSONObject = try JSONParser.JSONObjectWithData(response.data) + var pvideo = try BilibiliPvideo.init(object: json) + pvideo.cropImages() + block(pvideo) + return false + } + } + } + } diff --git a/iina+/Views/Base.lproj/Main.storyboard b/iina+/Views/Base.lproj/Main.storyboard index 6817e003..8d8fd6eb 100644 --- a/iina+/Views/Base.lproj/Main.storyboard +++ b/iina+/Views/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + @@ -1035,7 +1035,7 @@ - + @@ -1061,19 +1061,8 @@ - - - - - - - - - - - - + @@ -1084,7 +1073,7 @@ - + @@ -1098,7 +1087,7 @@ - + @@ -1109,38 +1098,69 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + - - - - - - - - - - + - - + - + - - - + + + + + + @@ -1164,7 +1184,7 @@ - diff --git a/iina+/Views/MainWindow/MainViewController.swift b/iina+/Views/MainWindow/MainViewController.swift index a5f2803d..c0b79114 100644 --- a/iina+/Views/MainWindow/MainViewController.swift +++ b/iina+/Views/MainWindow/MainViewController.swift @@ -57,13 +57,32 @@ class MainViewController: NSViewController { @IBOutlet var bilibiliArrayController: NSArrayController! @objc dynamic var bilibiliCards: [BilibiliCard] = [] let bilibili = Bilibili() + @IBOutlet weak var videoInfosContainerView: NSView! @IBAction func sendBilibiliURL(_ sender: Any) { if bilibiliTableView.selectedRow != -1 { - let aid = bilibiliCards[bilibiliTableView.selectedRow].aid - searchField.stringValue = "https://www.bilibili.com/video/av\(aid)" - searchField.becomeFirstResponder() - startSearch(self) + let card = bilibiliCards[bilibiliTableView.selectedRow] + let aid = card.aid + if card.videos == 1 { + searchField.stringValue = "https://www.bilibili.com/video/av\(aid)" + searchField.becomeFirstResponder() + startSearch(self) + } else if card.videos > 1 { + bilibili.getVideoList(aid, { infos in + if let selectVideoViewController = self.children.compactMap({ $0 as? SelectVideoViewController }).first { + DispatchQueue.main.async { + self.mainTabView.selectTabViewItem(at: 3) + selectVideoViewController.videoInfos = infos + } + } + }) { re in + do { + let _ = try re() + } catch let error { + Logger.log("Get video list error: \(error)") + } + } + } } } diff --git a/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.swift b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.swift new file mode 100644 index 00000000..a5b3195f --- /dev/null +++ b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.swift @@ -0,0 +1,19 @@ +// +// SelectVideoCollectionViewItem.swift +// iina+ +// +// Created by xjbeta on 2018/8/21. +// Copyright © 2018 xjbeta. All rights reserved. +// + +import Cocoa + +class SelectVideoCollectionViewItem: NSCollectionViewItem { + @IBOutlet weak var titleButton: NSButton! + @IBOutlet weak var titleTextField: NSTextField! + + override func viewDidLoad() { + super.viewDidLoad() + } + +} diff --git a/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.xib b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.xib new file mode 100644 index 00000000..f2adc0a7 --- /dev/null +++ b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.xib @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItemButton.swift b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItemButton.swift new file mode 100644 index 00000000..b8d15e3e --- /dev/null +++ b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItemButton.swift @@ -0,0 +1,48 @@ +// +// SelectVideoCollectionViewItemButton.swift +// iina+ +// +// Created by xjbeta on 2018/8/21. +// Copyright © 2018 xjbeta. All rights reserved. +// + +import Cocoa + +class SelectVideoCollectionViewItemButton: NSButton { + + override func draw(_ dirtyRect: NSRect) { + super.draw(dirtyRect) + + let selectionRect = NSInsetRect(bounds, 0, 0) + let selectionPath = NSBezierPath(roundedRect: selectionRect, xRadius: 3, yRadius: 3) + if isHighlighted { + NSColor.customHighlightColor.setFill() + } else { + NSColor.white.setFill() + } + selectionPath.fill() + + let style = NSMutableParagraphStyle() + style.lineBreakMode = .byWordWrapping + style.lineSpacing = 1 + style.alignment = .left +// style.lineHeightMultiple + + let str = NSMutableAttributedString(string: title, attributes: [.paragraphStyle: style]) + + + if let cell = cell as? NSButtonCell { + var rect = bounds + let padding: CGFloat = 8 + rect.origin.x += padding + rect.origin.y += padding + rect.size.width -= padding * 2 + rect.size.height -= padding * 2 + +// cell.lineBreakMode = .byTruncatingMiddle + cell.drawTitle(str, withFrame: rect, in: self) + } + } + +} + diff --git a/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoViewController.swift b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoViewController.swift new file mode 100644 index 00000000..645899d7 --- /dev/null +++ b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoViewController.swift @@ -0,0 +1,56 @@ +// +// SelectVideoViewController.swift +// iina+ +// +// Created by xjbeta on 2018/8/21. +// Copyright © 2018 xjbeta. All rights reserved. +// + +import Cocoa + +class SelectVideoViewController: NSViewController { + + @IBOutlet weak var collectionView: NSCollectionView! + + var videoInfos: [BilibiliSimpleVideoInfo] = [] { + didSet { + collectionView.reloadData() + } + } + + override func viewDidLoad() { + super.viewDidLoad() + + +// collectionView.register(NSNib.init(nibNamed: "SelectVideoCollectionViewItem", bundle: nil), forItemWithIdentifier: NSUserInterfaceItemIdentifier.init(rawValue: "SelectVideoCollectionViewItem")) + + + } + +} + +extension SelectVideoViewController: NSCollectionViewDataSource, NSCollectionViewDelegate { + func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int { + return videoInfos.count + } + + func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem { + let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "SelectVideoCollectionViewItem"), for: indexPath) + guard let selectVideoItem = item as? SelectVideoCollectionViewItem else { + return item + } + + let info = videoInfos[indexPath.item] + selectVideoItem.titleButton.title = "[\(info.page)] \(info.part)" + return selectVideoItem + } + + + + + + + + + +} From b70838d6587635d41a6fe2f270f28da669a4f35a Mon Sep 17 00:00:00 2001 From: xjbeta Date: Tue, 21 Aug 2018 21:00:17 +0800 Subject: [PATCH 15/25] Clickable collectionview item. --- iina+.xcodeproj/project.pbxproj | 4 +++ iina+/Views/Base.lproj/Main.storyboard | 1 + .../SelectVideoCollectionViewItem.swift | 1 - .../SelectVideoCollectionViewItem.xib | 29 +++++++++-------- .../SelectVideoCollectionViewItemView.swift | 32 +++++++++++++++++++ .../SelectVideoViewController.swift | 29 +++++++++-------- 6 files changed, 68 insertions(+), 28 deletions(-) create mode 100644 iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItemView.swift diff --git a/iina+.xcodeproj/project.pbxproj b/iina+.xcodeproj/project.pbxproj index 81bbe41d..27570cba 100644 --- a/iina+.xcodeproj/project.pbxproj +++ b/iina+.xcodeproj/project.pbxproj @@ -42,6 +42,7 @@ 016792E6212BDEE5003517A7 /* SelectVideoCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 016792E4212BDEE5003517A7 /* SelectVideoCollectionViewItem.swift */; }; 016792E7212BDEE5003517A7 /* SelectVideoCollectionViewItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = 016792E5212BDEE5003517A7 /* SelectVideoCollectionViewItem.xib */; }; 016792EC212BFB25003517A7 /* SelectVideoCollectionViewItemButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 016792EB212BFB25003517A7 /* SelectVideoCollectionViewItemButton.swift */; }; + 016792EE212C421F003517A7 /* SelectVideoCollectionViewItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 016792ED212C421F003517A7 /* SelectVideoCollectionViewItemView.swift */; }; 01683DD9211869AE0016A886 /* BilibiliLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01683DD8211869AE0016A886 /* BilibiliLoginViewController.swift */; }; 01683DDB2118905D0016A886 /* Bilibili.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01683DDA2118905D0016A886 /* Bilibili.swift */; }; 01683DDE211924160016A886 /* BilibiliViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01683DDD211924160016A886 /* BilibiliViewController.swift */; }; @@ -122,6 +123,7 @@ 016792E4212BDEE5003517A7 /* SelectVideoCollectionViewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectVideoCollectionViewItem.swift; sourceTree = ""; }; 016792E5212BDEE5003517A7 /* SelectVideoCollectionViewItem.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SelectVideoCollectionViewItem.xib; sourceTree = ""; }; 016792EB212BFB25003517A7 /* SelectVideoCollectionViewItemButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectVideoCollectionViewItemButton.swift; sourceTree = ""; }; + 016792ED212C421F003517A7 /* SelectVideoCollectionViewItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectVideoCollectionViewItemView.swift; sourceTree = ""; }; 01683DD8211869AE0016A886 /* BilibiliLoginViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BilibiliLoginViewController.swift; sourceTree = ""; }; 01683DDA2118905D0016A886 /* Bilibili.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bilibili.swift; sourceTree = ""; }; 01683DDD211924160016A886 /* BilibiliViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BilibiliViewController.swift; sourceTree = ""; }; @@ -253,6 +255,7 @@ 016792E0212BBB43003517A7 /* SelectVideoViewController.swift */, 016792E4212BDEE5003517A7 /* SelectVideoCollectionViewItem.swift */, 016792EB212BFB25003517A7 /* SelectVideoCollectionViewItemButton.swift */, + 016792ED212C421F003517A7 /* SelectVideoCollectionViewItemView.swift */, 016792E5212BDEE5003517A7 /* SelectVideoCollectionViewItem.xib */, ); path = SelectVideoCollectionView; @@ -428,6 +431,7 @@ 012601742119FBF400C9C639 /* BilibiliCardTableCellView.swift in Sources */, 01010127211DCAE8002F0F7F /* SidebarViewController.swift in Sources */, 01AEC8C220EFBCCF001406E8 /* MPVOption.swift in Sources */, + 016792EE212C421F003517A7 /* SelectVideoCollectionViewItemView.swift in Sources */, 01AEC8C920F1081C001406E8 /* Identifiers.swift in Sources */, 01010125211DBC27002F0F7F /* StringExtension.swift in Sources */, 0196CB6421214B4200BCD29E /* AdvancedViewController.swift in Sources */, diff --git a/iina+/Views/Base.lproj/Main.storyboard b/iina+/Views/Base.lproj/Main.storyboard index b9ae6573..60440210 100644 --- a/iina+/Views/Base.lproj/Main.storyboard +++ b/iina+/Views/Base.lproj/Main.storyboard @@ -1495,6 +1495,7 @@ Gw + diff --git a/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.swift b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.swift index a5b3195f..897dd3e5 100644 --- a/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.swift +++ b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.swift @@ -9,7 +9,6 @@ import Cocoa class SelectVideoCollectionViewItem: NSCollectionViewItem { - @IBOutlet weak var titleButton: NSButton! @IBOutlet weak var titleTextField: NSTextField! override func viewDidLoad() { diff --git a/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.xib b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.xib index f2adc0a7..329dda85 100644 --- a/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.xib +++ b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItem.xib @@ -8,29 +8,30 @@ - + - - + + - + + + + + + + + - - - - + + + + diff --git a/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItemView.swift b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItemView.swift new file mode 100644 index 00000000..2943ab02 --- /dev/null +++ b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoCollectionViewItemView.swift @@ -0,0 +1,32 @@ +// +// SelectVideoCollectionViewItemView.swift +// iina+ +// +// Created by xjbeta on 2018/8/21. +// Copyright © 2018 xjbeta. All rights reserved. +// + +import Cocoa + +class SelectVideoCollectionViewItemView: NSView { + + var isSelected: Bool = false { + didSet { + needsDisplay = true + } + } + + override func draw(_ dirtyRect: NSRect) { + super.draw(dirtyRect) + + let selectionRect = NSInsetRect(bounds, 0, 0) + let selectionPath = NSBezierPath(roundedRect: selectionRect, xRadius: 3, yRadius: 3) + if isSelected { + NSColor.customHighlightColor.setFill() + } else { + NSColor.white.setFill() + } + selectionPath.fill() + } + +} diff --git a/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoViewController.swift b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoViewController.swift index 645899d7..63a67f3f 100644 --- a/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoViewController.swift +++ b/iina+/Views/MainWindow/SelectVideoCollectionView/SelectVideoViewController.swift @@ -21,12 +21,7 @@ class SelectVideoViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() - -// collectionView.register(NSNib.init(nibNamed: "SelectVideoCollectionViewItem", bundle: nil), forItemWithIdentifier: NSUserInterfaceItemIdentifier.init(rawValue: "SelectVideoCollectionViewItem")) - - } - } extension SelectVideoViewController: NSCollectionViewDataSource, NSCollectionViewDelegate { @@ -41,16 +36,24 @@ extension SelectVideoViewController: NSCollectionViewDataSource, NSCollectionVie } let info = videoInfos[indexPath.item] - selectVideoItem.titleButton.title = "[\(info.page)] \(info.part)" +// selectVideoItem.titleButton.title = "[\(info.page)] \(info.part)" + selectVideoItem.titleTextField.stringValue = "[\(info.page)] \(info.part)" return selectVideoItem } + func collectionView(_ collectionView: NSCollectionView, didDeselectItemsAt indexPaths: Set) { + if let item = indexPaths.first?.item { + if let view = collectionView.item(at: item)?.view as? SelectVideoCollectionViewItemView { + view.isSelected = false + } + } + } - - - - - - - + func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set) { + if let item = indexPaths.first?.item { + if let view = collectionView.item(at: item)?.view as? SelectVideoCollectionViewItemView { + view.isSelected = true + } + } + } } From 6f99d1bb8ba3d657e2591582bde1d9ac58a1da82 Mon Sep 17 00:00:00 2001 From: xjbeta Date: Tue, 21 Aug 2018 21:30:06 +0800 Subject: [PATCH 16/25] Finish select video. --- iina+/Views/Base.lproj/Main.storyboard | 7 ++++--- iina+/Views/MainWindow/MainViewController.swift | 1 + .../SelectVideoViewController.swift | 15 ++++++++++----- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/iina+/Views/Base.lproj/Main.storyboard b/iina+/Views/Base.lproj/Main.storyboard index 60440210..18ba14d3 100644 --- a/iina+/Views/Base.lproj/Main.storyboard +++ b/iina+/Views/Base.lproj/Main.storyboard @@ -1336,15 +1336,15 @@ - + - - + + @@ -1500,6 +1500,7 @@ Gw +