diff --git a/Aerial/Source/Controllers/Preferences.swift b/Aerial/Source/Controllers/Preferences.swift index 64cf3654..01841ec5 100644 --- a/Aerial/Source/Controllers/Preferences.swift +++ b/Aerial/Source/Controllers/Preferences.swift @@ -78,6 +78,7 @@ final class Preferences { case newViewingMode = "newViewingMode" case newDisplayDict = "newDisplayDict" case logMilliseconds = "logMilliseconds" + case horizontalMargin = "horizontalMargin" } enum NewDisplayMode: Int { @@ -215,6 +216,7 @@ final class Preferences { defaultValues[.newViewingMode] = NewViewingMode.independent defaultValues[.newDisplayDict] = [String: Bool]() defaultValues[.logMilliseconds] = false + defaultValues[.horizontalMargin] = 0 // Set today's date as default let dateFormatter = DateFormatter() @@ -251,6 +253,15 @@ final class Preferences { } } + var horizontalMargin: Double? { + get { + return optionalValue(forIdentifier: .horizontalMargin) + } + set { + setValue(forIdentifier: .horizontalMargin, value: newValue) + } + } + var newDisplayMode: Int? { get { return optionalValue(forIdentifier: .newDisplayMode) diff --git a/Aerial/Source/Controllers/PreferencesWindowController.swift b/Aerial/Source/Controllers/PreferencesWindowController.swift index 3b5127e8..e7229585 100644 --- a/Aerial/Source/Controllers/PreferencesWindowController.swift +++ b/Aerial/Source/Controllers/PreferencesWindowController.swift @@ -213,6 +213,8 @@ final class PreferencesWindowController: NSWindowController, NSOutlineViewDataSo @IBOutlet var quitConfirmationPanel: NSPanel! @IBOutlet var logMillisecondsButton: NSButton! + @IBOutlet var displayMarginBox: NSBox! + @IBOutlet var horizontalDisplayMarginTextfield: NSTextField! var player: AVPlayer = AVPlayer() var videos: [AerialVideo]? @@ -421,6 +423,7 @@ final class PreferencesWindowController: NSWindowController, NSOutlineViewDataSo if !preferences.allowSkips { rightArrowKeyPlaysNextCheckbox.state = .off } + horizontalDisplayMarginTextfield.doubleValue = preferences.horizontalMargin! // Advanced panel if preferences.debugMode { @@ -886,6 +889,17 @@ final class PreferencesWindowController: NSWindowController, NSOutlineViewDataSo debugLog("UI newViewingModeClick: \(sender.indexOfSelectedItem)") preferences.newViewingMode = sender.indexOfSelectedItem displayView.needsDisplay = true + + if preferences.newViewingMode == Preferences.NewViewingMode.spanned.rawValue { + displayMarginBox.isHidden = false + } else { + displayMarginBox.isHidden = true + } + } + + @IBAction func horizontalDisplayMarginChange(_ sender: NSTextField) { + debugLog("UI horizontalDisplayMarginChange \(sender.stringValue)") + preferences.horizontalMargin = sender.doubleValue } // MARK: - Text panel diff --git a/Aerial/Source/Models/DisplayDetection.swift b/Aerial/Source/Models/DisplayDetection.swift index 8cb06ac7..1cc8795a 100644 --- a/Aerial/Source/Models/DisplayDetection.swift +++ b/Aerial/Source/Models/DisplayDetection.swift @@ -42,6 +42,9 @@ final class DisplayDetection: NSObject { static let sharedInstance = DisplayDetection() var screens = [Screen]() + var cmInPoints: CGFloat = 40 + var maxLeftScreens: CGFloat = 0 + var maxBelowScreens: CGFloat = 0 // MARK: - Lifecycle override init() { @@ -72,8 +75,13 @@ final class DisplayDetection: NSObject { var rect = CGDisplayBounds(currentDisplay) if isMain == 0 { rect = convertTopLeftToBottomLeft(rect: rect) + } else { + // We calculate the equivalent of a centimeter in points on the main screen as a reference + let mmsize = CGDisplayScreenSize(currentDisplay) + let wide = CGDisplayPixelsWide(currentDisplay) + cmInPoints = CGFloat(wide) / CGFloat(mmsize.width) * 10 + debugLog("1cm = \(cmInPoints) points") } - screens.append(Screen(id: currentDisplay, width: CGDisplayPixelsWide(currentDisplay), height: CGDisplayPixelsHigh(currentDisplay), @@ -97,6 +105,7 @@ final class DisplayDetection: NSObject { for screen in screens { debugLog("\(screen)") } + debugLog("\(getGlobalScreenRect())") debugLog("***Display Detection Done***") } @@ -106,12 +115,33 @@ final class DisplayDetection: NSObject { func calculateZeroedOrigins() { let orect = getGlobalScreenRect() + // First we check for the screen relative position and calculate how many screens we have horizontally + // TODO Vertical + H/V mix for screen in screens { - screen.zeroedOrigin = CGPoint(x: screen.bottomLeftFrame.origin.x - orect.origin.x, + debugLog("src orig : \(screen.bottomLeftFrame.origin)") + var leftScreens: CGFloat = 0 + // Very rough, horizontal spans only + for otherScreen in screens { + if otherScreen.bottomLeftFrame.origin.x != screen.bottomLeftFrame.origin.x && + otherScreen.bottomLeftFrame.origin.x < screen.bottomLeftFrame.origin.x { + leftScreens += 1 + } + } + + if leftScreens > maxLeftScreens { + maxLeftScreens = leftScreens + } + + screen.zeroedOrigin = CGPoint(x: screen.bottomLeftFrame.origin.x - orect.origin.x + (leftScreens * leftMargin()), y: screen.bottomLeftFrame.origin.y - orect.origin.y) } } + func leftMargin() -> CGFloat { + let preferences = Preferences.sharedInstance + return cmInPoints * CGFloat(preferences.horizontalMargin!) + } + func findScreenWith(frame: CGRect) -> Screen? { for screen in screens where frame == screen.bottomLeftFrame { return screen @@ -146,7 +176,7 @@ final class DisplayDetection: NSObject { } } - return CGRect(x: minX, y: minY, width: maxX-minX, height: maxY-minY) + return CGRect(x: minX, y: minY, width: maxX-minX+(maxLeftScreens*leftMargin()), height: maxY-minY) } func getZeroedActiveSpannedRect() -> CGRect { @@ -172,7 +202,7 @@ final class DisplayDetection: NSObject { let orect = getGlobalScreenRect() minX -= orect.origin.x minY -= orect.origin.y - return CGRect(x: minX, y: minY, width: width, height: height) + return CGRect(x: minX, y: minY, width: width+(maxLeftScreens*leftMargin()), height: height) } // NSScreen coordinates are with a bottom left origin, whereas CGDisplay diff --git a/Aerial/Source/Views/AerialView.swift b/Aerial/Source/Views/AerialView.swift index eed49414..a931a610 100644 --- a/Aerial/Source/Views/AerialView.swift +++ b/Aerial/Source/Views/AerialView.swift @@ -361,7 +361,7 @@ final class AerialView: ScreenSaverView { playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill } playerLayer.autoresizingMask = [CAAutoresizingMask.layerWidthSizable, CAAutoresizingMask.layerHeightSizable] - + // In case of span mode we need to compute the size of our layer if preferences.newViewingMode == Preferences.NewViewingMode.spanned.rawValue && !isPreview { let zRect = displayDetection.getZeroedActiveSpannedRect() @@ -371,6 +371,7 @@ final class AerialView: ScreenSaverView { y: zRect.origin.y - scr.zeroedOrigin.y, width: zRect.width, height: zRect.height) + debugLog("tRect : \(tRect)") playerLayer.frame = tRect //playerLayer.bounds = layer.bounds } else { @@ -583,7 +584,7 @@ final class AerialView: ScreenSaverView { debugLog("\(self.description) streaming video (not fully available offline) : \(video.url)") } else { let localurl = URL(fileURLWithPath: VideoCache.cachePath(forVideo: video)!) - var localitem = AVPlayerItem(url: localurl) + let localitem = AVPlayerItem(url: localurl) player.replaceCurrentItem(with: localitem) debugLog("\(self.description) playing video (OFFLINE MODE) : \(localurl)") } @@ -631,10 +632,14 @@ final class AerialView: ScreenSaverView { if preferences.allowSkips { if event.keyCode == 124 { - //playNextVideo() - // We need to skip forward all our views - for view in AerialView.instanciatedViews { - view.playNextVideo() + // If we share, just call this on our main view + if AerialView.sharingPlayers { + playNextVideo() + } else { + // If we do independant playback we have to skip all views + for view in AerialView.instanciatedViews { + view.playNextVideo() + } } } else { self.nextResponder!.keyDown(with: event) diff --git a/Resources/PreferencesWindow.xib b/Resources/PreferencesWindow.xib index 75d2dc89..19cbfe11 100644 --- a/Resources/PreferencesWindow.xib +++ b/Resources/PreferencesWindow.xib @@ -45,6 +45,7 @@ + @@ -69,6 +70,7 @@ + @@ -541,7 +543,7 @@ is disabled - + @@ -635,6 +637,84 @@ is disabled + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1774,7 +1854,7 @@ Shift, but macOS 10.12.4 or above and a compatible Mac are required) - +