OSDN Git Service

分散していたスクリーンショットディレクトリを表すプロパティを集約した
[kcd/KCD.git] / KCD / GameViewController.swift
index 542b90e..a87dc7b 100644 (file)
@@ -10,28 +10,26 @@ import Cocoa
 import WebKit
 import JavaScriptCore
 
-fileprivate extension Selector {
-    static let reloadContent = #selector(GameViewController.reloadContent(_:))
-    static let deleteCacheAndReload = #selector(GameViewController.deleteCacheAndReload(_:))
-    static let screenShot = #selector(GameViewController.screenShot(_:))
-}
-
-class GameViewController: NSViewController {
+final class GameViewController: NSViewController {
+    
     private static let gamePageURL = "http://www.dmm.com/netgame/social/-/gadgets/=/app_id=854854/"
     private static let loginPageURLPrefix = "https://www.dmm.com/my/-/login/=/"
     
-    @IBOutlet var webView: WebView!
+    @IBOutlet private var webView: WebView!
     
-    override var nibName: String! {
-        return "GameViewController"
+    override var nibName: NSNib.Name {
+        
+        return .nibName(instanceOf: self)
     }
     
-    fileprivate var flashTopLeft = NSPoint(x: 2600, y: 1445)
+    private var flashTopLeft = NSPoint(x: 2600, y: 1445)
     private var clipView: NSClipView {
+        
         return view as! NSClipView  // swiftlint:disable:this force_cast
     }
     
     override func viewDidLoad() {
+        
         super.viewDidLoad()
         
         clipView.documentView = webView
@@ -43,97 +41,223 @@ class GameViewController: NSViewController {
         webView.applicationNameForUserAgent = AppDelegate.shared.appNameForUserAgent
         webView.mainFrameURL = GameViewController.gamePageURL
     }
+    
     func adjustFlash() {
+        
         webView.superview?.scroll(flashTopLeft)
     }
     
     @IBAction func reloadContent(_ sender: AnyObject?) {
-        guard let _ = webView.mainFrameURL
-            else {
-                webView.mainFrameURL = GameViewController.gamePageURL
-                return
+        
+        guard let _ = webView.mainFrameURL else {
+            
+            webView.mainFrameURL = GameViewController.gamePageURL
+            
+            return
         }
+        
         // ゲームページでない場合はゲームページを表示する
         if webView.mainFrameURL != GameViewController.gamePageURL {
+            
             webView.mainFrameURL = GameViewController.gamePageURL
+            
             return
         }
         if webView.mainFrameURL.hasPrefix(GameViewController.loginPageURLPrefix) {
+            
             webView.reload(sender)
+            
             return
         }
         
         adjustFlash()
         
-        let prevDate = UserDefaults.standard.prevReloadDate
-        if prevDate != nil {
-            let now = Date(timeIntervalSinceNow: 0.0)
-            if now.timeIntervalSince(prevDate!) < 1 * 60 {
-                let untilDate = prevDate?.addingTimeInterval(1 * 60)
-                let date = DateFormatter.localizedString(from: untilDate!, dateStyle: .none, timeStyle: .medium)
-                let alert = NSAlert()
-                alert.messageText = NSLocalizedString("Reload interval is too short?", comment: "")
-                let format = NSLocalizedString("Reload interval is too short.\nWait until %@.", comment: "")
-                alert.informativeText = String(format: format, date)
-                alert.runModal()
-                
-                return
-            }
+        let prevDate = UserDefaults.standard[.prevReloadDate]
+        if Date(timeIntervalSinceNow: 0.0).timeIntervalSince(prevDate) < 1 * 60 {
+            
+            let untilDate = prevDate.addingTimeInterval(1 * 60)
+            let date = DateFormatter.localizedString(from: untilDate, dateStyle: .none, timeStyle: .medium)
+            let alert = NSAlert()
+            alert.messageText = LocalizedStrings.reloadTimeShortenMessage.string
+            let format = LocalizedStrings.reloadTimeShortenInfo.string
+            alert.informativeText = String(format: format, date)
+            alert.runModal()
+            
+            return
         }
         
         webView.reload(sender)
         
-        UserDefaults.standard.prevReloadDate = Date(timeIntervalSinceNow: 0.0)
+        UserDefaults.standard[.prevReloadDate] = Date(timeIntervalSinceNow: 0.0)
     }
+    
     @IBAction func deleteCacheAndReload(_ sender: AnyObject?) {
+        
         let panel = ProgressPanel()
+        
+        guard let window = view.window else {
+            
+            return
+        }
+        guard let panelWindow = panel.window else {
+            
+            return
+        }
+        
         panel.title = ""
-        panel.message = NSLocalizedString("Deleting caches...", comment: "Deleting caches...")
+        panel.message = LocalizedStrings.deletingCacheInfo.string
         panel.animate = true
         
-        view.window?.beginSheet(panel.window!, completionHandler: { _ in
-            NSSound(named: "Submarine")?.play()
-        })
+        window.beginSheet(panelWindow) { _ in NSSound(named: NSSound.Name("Submarine"))?.play() }
         
         AppDelegate.shared.clearCache()
         
-        view.window?.endSheet(panel.window!)
+        window.endSheet(panelWindow)
     }
-    @IBAction func screenShot(_ sender: AnyObject?) {
+    
+    func screenshotOld() {
+        
         let frame = webView.visibleRect
-        let screenshotBorder = UserDefaults.standard.screenShotBorderWidth
+        let screenshotBorder = UserDefaults.standard[.screenShotBorderWidth]
         let f = frame.insetBy(dx: -screenshotBorder, dy: -screenshotBorder)
-        guard let rep = webView.bitmapImageRepForCachingDisplay(in: f) else { return }
+        
+        guard let rep = webView.bitmapImageRepForCachingDisplay(in: f) else {
+            
+            return
+        }
+        
         webView.cacheDisplay(in: frame, to: rep)
-        AppDelegate.shared.screenshotListWindowController.registerScreenshot(rep, fromOnScreen: .zero)
+        
+        ScreenshotRegister(ApplicationDirecrories.shared.screenshotSaveDirectoryURL)
+            .registerScreenshot(rep, name: localizedAppName())
+    }
+    
+    @available(OSX 10.13, *)
+    func screenshot() {
+        
+        let frame = view.visibleRect
+        let screenshotBorder = UserDefaults.standard[.screenShotBorderWidth]
+        let f = frame.insetBy(dx: -screenshotBorder, dy: -screenshotBorder)
+        let windowCoordinateFrame = view.convert(f, to: nil)
+        
+        guard let window = view.window else {
+            
+            Logger.shared.log("Can not get window")
+            
+            return
+        }
+        let screenCoordinsteFrame = window.convertToScreen(windowCoordinateFrame)
+        
+        guard let screen = NSScreen.main else {
+            
+            Logger.shared.log("Can not get Screen")
+            
+            return
+        }
+        let scFrame = screen.frame
+        
+        guard let cxt = window.graphicsContext?.cgContext else {
+            
+            Logger.shared.log("Cannot get Context")
+            
+            return
+        }
+        let deviceCoordinateFrame = cxt.convertToDeviceSpace(screenCoordinsteFrame)
+        let raio = deviceCoordinateFrame.size.width / screenCoordinsteFrame.size.width
+        
+        let trimRect = CGRect(x: raio * screenCoordinsteFrame.origin.x,
+                              y: raio * (scFrame.size.height - screenCoordinsteFrame.origin.y - screenCoordinsteFrame.size.height),
+                              width: raio * screenCoordinsteFrame.size.width,
+                              height: raio * screenCoordinsteFrame.size.height)
+        
+        guard let fullSizeImage = CGDisplayCreateImage(CGMainDisplayID()) else {
+            
+            Logger.shared.log("Can not get Image")
+            
+            return
+        }
+        
+        guard let image = fullSizeImage.cropping(to: trimRect) else {
+            
+            Logger.shared.log("Can not trim image")
+            
+            return
+        }
+        
+        let rep = NSBitmapImageRep(cgImage: image)
+        
+        if rep.size != NSSize(width: 800, height: 480) {
+            
+            rep.size = NSSize(width: 800, height: 480)
+        }
+        
+        ScreenshotRegister(ApplicationDirecrories.shared.screenshotSaveDirectoryURL)
+            .registerScreenshot(rep, name: localizedAppName())
+    }
+    
+    @IBAction func screenShot(_ sender: AnyObject?) {
+        
+        if #available(OSX 10.13, *) {
+            
+            screenshot()
+            
+        } else {
+            
+            screenshotOld()
+        }
     }
     
     override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
-        if menuItem.action == .reloadContent {
-            guard let _ = webView.mainFrame,
-                let frameURL = webView.mainFrameURL
-                else { return true }
+        
+        guard let action: Selector = menuItem.action else {
+            
+            return false
+        }
+        
+        switch action {
+            
+        case #selector(GameViewController.reloadContent(_:)):
+            
+            guard let _ = webView.mainFrame else {
+                
+                return true
+            }
+            guard let frameURL = webView.mainFrameURL else {
+                
+                return true
+            }
+            
             switch frameURL {
+                
             case GameViewController.gamePageURL:
-                menuItem.title = NSLocalizedString("Reload", comment: "Reload menu, reload")
+                menuItem.title = LocalizedStrings.reload.string
+                
             case let s where s.hasPrefix(GameViewController.loginPageURLPrefix):
-                menuItem.title = NSLocalizedString("Reload", comment: "Reload menu, reload")
+                menuItem.title = LocalizedStrings.reload.string
+                
             default:
-                menuItem.title = NSLocalizedString("Back To Game", comment: "Reload menu, back to game")
+                menuItem.title = LocalizedStrings.backToGame.string
+                
             }
+            
             return true
-        }
-        if menuItem.action == .deleteCacheAndReload {
+            
+        case #selector(GameViewController.deleteCacheAndReload(_:)):
+            
             return true
-        }
-        if menuItem.action == .screenShot {
+            
+        case #selector(GameViewController.screenShot(_:)):
+            
             return true
+            
+        default: return false
+            
         }
-        return false
     }
 }
 
 extension GameViewController: WebFrameLoadDelegate, WebUIDelegate {
+    
     private static let excludeMenuItemTag = [
         WebMenuItemTagOpenLinkInNewWindow,
         WebMenuItemTagDownloadLinkToDisk,
@@ -146,14 +270,31 @@ extension GameViewController: WebFrameLoadDelegate, WebUIDelegate {
     ]
     
     func webView(_ sender: WebView!, didFinishLoadFor frame: WebFrame!) {
-        guard let path = frame.dataSource?.initialRequest.url?.path else { return }
         
-        let handler: (JSContext?, JSValue?) -> Void = { (context, exception) in
-            print("Caught exception in evaluteScript -> \(exception)")
+        guard let path = frame.dataSource?.initialRequest.url?.path else {
+            
+            return
+        }
+        
+        let handler: (JSContext?, JSValue?) -> Void = { (_, exception) in
+            
+            if let exception = exception {
+                
+                print("Caught exception in evaluteScript -> \(exception)")
+                
+            } else {
+                
+                print("Caught exception in evaluteScript")
+            }
         }
         
         if path.hasSuffix("gadgets/ifr") {
-            guard let context = frame.javaScriptContext else { return }
+            
+            guard let context = frame.javaScriptContext else {
+                
+                return
+            }
+            
             context.exceptionHandler = handler
             context.evaluateScript(
                 ["var emb = document.getElementById('flashWrap');",
@@ -166,8 +307,14 @@ extension GameViewController: WebFrameLoadDelegate, WebUIDelegate {
             let left = context.objectForKeyedSubscript("aleft").toDouble()
             flashTopLeft = NSPoint(x: CGFloat(left), y: webView.frame.size.height - CGFloat(top) - 480)
         }
+        
         if path.hasSuffix("app_id=854854") {
-            guard let context = frame.javaScriptContext else { return }
+            
+            guard let context = frame.javaScriptContext else {
+                
+                return
+            }
+            
             context.exceptionHandler = handler
             context.evaluateScript(
                 ["var iframe = document.getElementById('game_frame');",
@@ -181,20 +328,27 @@ extension GameViewController: WebFrameLoadDelegate, WebUIDelegate {
                     .reduce("", +)
             )
             let validIframe = context.objectForKeyedSubscript("validIframe").toInt32()
-            guard validIframe != 0 else { return }
+            
+            guard validIframe != 0 else {
+                
+                return
+            }
+            
             let top = context.objectForKeyedSubscript("atop").toDouble()
             let left = context.objectForKeyedSubscript("aleft").toDouble()
             flashTopLeft = NSPoint(x: flashTopLeft.x + CGFloat(left), y: flashTopLeft.y - CGFloat(top))
+            
             adjustFlash()
         }
     }
     
-    func webView(_ sender: WebView!,
-                 contextMenuItemsForElement element: [AnyHashable: Any]!,
-                 defaultMenuItems: [Any]!) -> [Any]! {
-        guard let menuItems = defaultMenuItems as? [NSMenuItem] else { return [] }
-        return menuItems.flatMap {
-            GameViewController.excludeMenuItemTag.contains($0.tag) ? nil : $0
+    func webView(_ sender: WebView!, contextMenuItemsForElement element: [AnyHashable: Any]!, defaultMenuItems: [Any]!) -> [Any]! {
+        
+        guard let menuItems = defaultMenuItems as? [NSMenuItem] else {
+            
+            return []
         }
+        
+        return menuItems.filter { !GameViewController.excludeMenuItemTag.contains($0.tag) }
     }
 }