diff --git a/Rectangle.xcodeproj/project.pbxproj b/Rectangle.xcodeproj/project.pbxproj index 0e5d2a280..f81e1d812 100644 --- a/Rectangle.xcodeproj/project.pbxproj +++ b/Rectangle.xcodeproj/project.pbxproj @@ -97,6 +97,7 @@ 98FD7C5F2687BC14009E9DAF /* FirstThreeFourthsCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98FD7C5E2687BC14009E9DAF /* FirstThreeFourthsCalculation.swift */; }; 98FD7C612687BCB6009E9DAF /* LastThreeFourthsCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98FD7C602687BCB6009E9DAF /* LastThreeFourthsCalculation.swift */; }; CC0B7937429AC28C21ABF5B4 /* Pods_RectangleLauncher.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F2D8480CC730811C953FC1B6 /* Pods_RectangleLauncher.framework */; }; + D0423D8327A8D31D008A4894 /* HorizontalThirdsRepeated.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0423D8227A8D31D008A4894 /* HorizontalThirdsRepeated.swift */; }; D04CE3002781794E00BD47B3 /* TopLeftNinthCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04CE2FF2781794E00BD47B3 /* TopLeftNinthCalculation.swift */; }; D04CE30227817A6100BD47B3 /* TopCenterNinthCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04CE30127817A6100BD47B3 /* TopCenterNinthCalculation.swift */; }; D04CE30427817A6F00BD47B3 /* TopRightNinthCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04CE30327817A6F00BD47B3 /* TopRightNinthCalculation.swift */; }; @@ -107,6 +108,10 @@ D04CE30E27817AB500BD47B3 /* BottomCenterNinthCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04CE30D27817AB500BD47B3 /* BottomCenterNinthCalculation.swift */; }; D04CE31027817ABE00BD47B3 /* BottomRightNinthCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04CE30F27817ABE00BD47B3 /* BottomRightNinthCalculation.swift */; }; D04CE31227817C9B00BD47B3 /* NinthsRepeated.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04CE31127817C9B00BD47B3 /* NinthsRepeated.swift */; }; + D0CFE33127A8CAED004DA47B /* TopLeftThirdCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CFE33027A8CAED004DA47B /* TopLeftThirdCalculation.swift */; }; + D0CFE33327A8CCB1004DA47B /* TopRightThirdCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CFE33227A8CCB1004DA47B /* TopRightThirdCalculation.swift */; }; + D0CFE33527A8CD16004DA47B /* BottomLeftThirdCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CFE33427A8CD16004DA47B /* BottomLeftThirdCalculation.swift */; }; + D0CFE33727A8CD51004DA47B /* BottomRightThirdCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0CFE33627A8CD51004DA47B /* BottomRightThirdCalculation.swift */; }; F0A0DFB36FCC3FCE6E184500 /* Pods_Rectangle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20A533B9F2D3215AC7B85D1F /* Pods_Rectangle.framework */; }; /* End PBXBuildFile section */ @@ -272,6 +277,7 @@ 98FE8976246E79C400871535 /* zh-Hant-HK */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant-HK"; path = "zh-Hant-HK.lproj/Main.strings"; sourceTree = ""; }; 98FE8977246E79C400871535 /* zh-Hant-HK */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant-HK"; path = "zh-Hant-HK.lproj/Main.strings"; sourceTree = ""; }; BFFF93EBEA6E2FF7245A7CF5 /* Pods-Rectangle.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rectangle.release.xcconfig"; path = "Target Support Files/Pods-Rectangle/Pods-Rectangle.release.xcconfig"; sourceTree = ""; }; + D0423D8227A8D31D008A4894 /* HorizontalThirdsRepeated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HorizontalThirdsRepeated.swift; sourceTree = ""; }; D04CE2FF2781794E00BD47B3 /* TopLeftNinthCalculation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopLeftNinthCalculation.swift; sourceTree = ""; }; D04CE30127817A6100BD47B3 /* TopCenterNinthCalculation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopCenterNinthCalculation.swift; sourceTree = ""; }; D04CE30327817A6F00BD47B3 /* TopRightNinthCalculation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopRightNinthCalculation.swift; sourceTree = ""; }; @@ -282,6 +288,10 @@ D04CE30D27817AB500BD47B3 /* BottomCenterNinthCalculation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BottomCenterNinthCalculation.swift; sourceTree = ""; }; D04CE30F27817ABE00BD47B3 /* BottomRightNinthCalculation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BottomRightNinthCalculation.swift; sourceTree = ""; }; D04CE31127817C9B00BD47B3 /* NinthsRepeated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NinthsRepeated.swift; sourceTree = ""; }; + D0CFE33027A8CAED004DA47B /* TopLeftThirdCalculation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopLeftThirdCalculation.swift; sourceTree = ""; }; + D0CFE33227A8CCB1004DA47B /* TopRightThirdCalculation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopRightThirdCalculation.swift; sourceTree = ""; }; + D0CFE33427A8CD16004DA47B /* BottomLeftThirdCalculation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BottomLeftThirdCalculation.swift; sourceTree = ""; }; + D0CFE33627A8CD51004DA47B /* BottomRightThirdCalculation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BottomRightThirdCalculation.swift; sourceTree = ""; }; DE4AE568B8BDB98BF602D588 /* Pods-RectangleMAS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RectangleMAS.release.xcconfig"; path = "Target Support Files/Pods-RectangleMAS/Pods-RectangleMAS.release.xcconfig"; sourceTree = ""; }; E2625F45B180F733E8508494 /* Pods-RectangleMAS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RectangleMAS.debug.xcconfig"; path = "Target Support Files/Pods-RectangleMAS/Pods-RectangleMAS.debug.xcconfig"; sourceTree = ""; }; F2D8480CC730811C953FC1B6 /* Pods_RectangleLauncher.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RectangleLauncher.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -419,6 +429,11 @@ D04CE30B27817AA900BD47B3 /* BottomLeftNinthCalculation.swift */, D04CE30D27817AB500BD47B3 /* BottomCenterNinthCalculation.swift */, D04CE30F27817ABE00BD47B3 /* BottomRightNinthCalculation.swift */, + D0CFE33027A8CAED004DA47B /* TopLeftThirdCalculation.swift */, + D0CFE33227A8CCB1004DA47B /* TopRightThirdCalculation.swift */, + D0CFE33427A8CD16004DA47B /* BottomLeftThirdCalculation.swift */, + D0CFE33627A8CD51004DA47B /* BottomRightThirdCalculation.swift */, + D0423D8227A8D31D008A4894 /* HorizontalThirdsRepeated.swift */, ); path = WindowCalculation; sourceTree = ""; @@ -847,12 +862,14 @@ 98A009BB2512539900CFBF0C /* BottomLeftSixthCalculation.swift in Sources */, 9821402322B3886100ABFB3F /* CenterCalculation.swift in Sources */, 98A009AB2512491300CFBF0C /* CenterHalfCalculation.swift in Sources */, + D0CFE33327A8CCB1004DA47B /* TopRightThirdCalculation.swift in Sources */, 9821403522B38A2B00ABFB3F /* UpperRightCalculation.swift in Sources */, 9824702F22AFA2E50037B409 /* AccessibilityAuthorization.swift in Sources */, 988D066322EB4CA5004EABD7 /* FirstTwoThirdsCalculation.swift in Sources */, D04CE30A27817A9F00BD47B3 /* MiddleRightNinthCalculation.swift in Sources */, 98BEFA482620DEDD00D9D54F /* NSImageExtension.swift in Sources */, 98FA9497235A2D7600F95C4F /* RepeatedExecutionsCalculation.swift in Sources */, + D0CFE33727A8CD51004DA47B /* BottomRightThirdCalculation.swift in Sources */, 9824705122B28D7A0037B409 /* LeftRightHalfCalculation.swift in Sources */, 9824703D22B13C7E0037B409 /* AccessibilityElement.swift in Sources */, 98D1441324560B1E0090C603 /* AlertUtil.swift in Sources */, @@ -865,6 +882,8 @@ 98A009AF2512517900CFBF0C /* SecondFourthCalculation.swift in Sources */, D04CE30C27817AA900BD47B3 /* BottomLeftNinthCalculation.swift in Sources */, 9821406022B3EFB200ABFB3F /* Defaults.swift in Sources */, + D0CFE33527A8CD16004DA47B /* BottomLeftThirdCalculation.swift in Sources */, + D0CFE33127A8CAED004DA47B /* TopLeftThirdCalculation.swift in Sources */, 98192DDA270F606C00015E66 /* Debounce.swift in Sources */, D04CE3002781794E00BD47B3 /* TopLeftNinthCalculation.swift in Sources */, 9821403122B38A0500ABFB3F /* TopHalfCalculation.swift in Sources */, @@ -895,6 +914,7 @@ 98C275672322E2DA009B9292 /* WindowHistory.swift in Sources */, 9821403722B3D16700ABFB3F /* MaximizeHeightCalculation.swift in Sources */, 9824704122B186D00037B409 /* WindowManager.swift in Sources */, + D0423D8327A8D31D008A4894 /* HorizontalThirdsRepeated.swift in Sources */, 98C97FFD25893B040061F01F /* Config.swift in Sources */, 989DA30E243FC0DF008C7AA4 /* WelcomeViewController.swift in Sources */, 98C27561231FFA5F009B9292 /* SnappingManager.swift in Sources */, diff --git a/Rectangle/WindowAction.swift b/Rectangle/WindowAction.swift index fb54e5231..d43143bb2 100644 --- a/Rectangle/WindowAction.swift +++ b/Rectangle/WindowAction.swift @@ -66,7 +66,11 @@ enum WindowAction: Int { middleRightNinth = 50, bottomLeftNinth = 51, bottomCenterNinth = 52, - bottomRightNinth = 53 + bottomRightNinth = 53, + topLeftThird = 54, + topRightThird = 55, + bottomLeftThird = 56, + bottomRightThird = 57 // Order matters here - it's used in the menu static let active = [leftHalf, rightHalf, centerHalf, topHalf, bottomHalf, @@ -81,6 +85,7 @@ enum WindowAction: Int { topLeftNinth, topCenterNinth, topRightNinth, middleLeftNinth, middleCenterNinth, middleRightNinth, bottomLeftNinth, bottomCenterNinth, bottomRightNinth, + topLeftThird, topRightThird, bottomLeftThird, bottomRightThird, ] func post() { @@ -157,6 +162,10 @@ enum WindowAction: Int { case .bottomLeftNinth: return "bottomLeftNinth" case .bottomCenterNinth: return "bottomCenterNinth" case .bottomRightNinth: return "bottomRightNinth" + case .topLeftThird: return "topLeftThird" + case .topRightThird: return "topRightThird" + case .bottomLeftThird: return "bottomLeftThird" + case .bottomRightThird: return "bottomRightThird" } } @@ -284,6 +293,8 @@ enum WindowAction: Int { value = "Bottom Right Sixth" case .topLeftNinth, .topCenterNinth, .topRightNinth, .middleLeftNinth, .middleCenterNinth, .middleRightNinth, .bottomLeftNinth, .bottomCenterNinth, .bottomRightNinth: return nil + case .topLeftThird, .topRightThird, .bottomLeftThird, .bottomRightThird: + return nil case .specified, .reverseAll: return nil } @@ -409,6 +420,10 @@ enum WindowAction: Int { case .bottomLeftNinth: return NSImage() case .bottomCenterNinth: return NSImage() case .bottomRightNinth: return NSImage() + case .topLeftThird: return NSImage() + case .topRightThird: return NSImage() + case .bottomLeftThird: return NSImage() + case .bottomRightThird: return NSImage() case .specified, .reverseAll: return NSImage() } } @@ -436,7 +451,8 @@ enum WindowAction: Int { switch self { case .leftHalf, .rightHalf, .bottomHalf, .topHalf, .centerHalf, .bottomLeft, .bottomRight, .topLeft, .topRight, .firstThird, .firstTwoThirds, .centerThird, .lastTwoThirds, .lastThird, .firstFourth, .secondFourth, .thirdFourth, .lastFourth, .firstThreeFourths, .lastThreeFourths, .topLeftSixth, .topCenterSixth, .topRightSixth, .bottomLeftSixth, .bottomCenterSixth, .bottomRightSixth, - .topLeftNinth, .topCenterNinth, .topRightNinth, .middleLeftNinth, .middleCenterNinth, .middleRightNinth, .bottomLeftNinth, .bottomCenterNinth, .bottomRightNinth: + .topLeftNinth, .topCenterNinth, .topRightNinth, .middleLeftNinth, .middleCenterNinth, .middleRightNinth, .bottomLeftNinth, .bottomCenterNinth, .bottomRightNinth, + .topLeftThird, .topRightThird, .bottomLeftThird, .bottomRightThird: return .both case .moveUp, .moveDown: return Defaults.resizeOnDirectionalMove.enabled ? .vertical : .none; @@ -532,6 +548,11 @@ enum SubWindowAction { bottomLeftNinth, bottomCenterNinth, bottomRightNinth, + + topLeftThird, + topRightThird, + bottomLeftThird, + bottomRightThird, maximize @@ -590,6 +611,10 @@ enum SubWindowAction { case .bottomLeftNinth: return [.top, .right] case .bottomCenterNinth: return [.left, .top, .right] case .bottomRightNinth: return [.left, .top] + case .topLeftThird: return [.right, .bottom] + case .topRightThird: return [.left, .bottom] + case .bottomLeftThird: return [.right, .top] + case .bottomRightThird: return [.left, .top] case .maximize: return .none } } diff --git a/Rectangle/WindowCalculation/BottomLeftThirdCalculation.swift b/Rectangle/WindowCalculation/BottomLeftThirdCalculation.swift new file mode 100644 index 000000000..3a84b6dcf --- /dev/null +++ b/Rectangle/WindowCalculation/BottomLeftThirdCalculation.swift @@ -0,0 +1,51 @@ +// +// BottomLeftThirdCalculation.swift +// Rectangle +// +// Created by Daniel Schultz on 1/2/22. +// Copyright © 2022 Ryan Hanson. All rights reserved. +// + +import Foundation + +class BottomLeftThirdCalculation: WindowCalculation, OrientationAware, HorizontalThirdsRepeated { + + override func calculateRect(_ params: RectCalculationParameters) -> RectResult { + let visibleFrameOfScreen = params.visibleFrameOfScreen + + guard Defaults.subsequentExecutionMode.value != .none, + let last = params.lastAction, + let lastSubAction = last.subAction + else { + return orientationBasedRect(visibleFrameOfScreen) + } + + if last.action != .bottomLeftThird { + return orientationBasedRect(visibleFrameOfScreen) + } + + if let calculation = self.nextCalculation(subAction: lastSubAction, direction: .right) { + return calculation(visibleFrameOfScreen) + } + + return orientationBasedRect(visibleFrameOfScreen) + } + + func landscapeRect(_ visibleFrameOfScreen: CGRect) -> RectResult { + var rect = visibleFrameOfScreen + rect.size.width = floor(2.0 * visibleFrameOfScreen.width / 3.0) + rect.size.height = floor(visibleFrameOfScreen.height / 2.0) + rect.origin.y = visibleFrameOfScreen.minY + rect.origin.x = visibleFrameOfScreen.minX + return RectResult(rect, subAction: .bottomLeftThird) + } + + func portraitRect(_ visibleFrameOfScreen: CGRect) -> RectResult { + var rect = visibleFrameOfScreen + rect.size.width = floor(visibleFrameOfScreen.width / 2.0) + rect.size.height = floor(2.0 * visibleFrameOfScreen.height / 3.0) + rect.origin.y = visibleFrameOfScreen.minY + rect.origin.x = visibleFrameOfScreen.minX + return RectResult(rect, subAction: .bottomLeftThird) + } +} diff --git a/Rectangle/WindowCalculation/BottomRightThirdCalculation.swift b/Rectangle/WindowCalculation/BottomRightThirdCalculation.swift new file mode 100644 index 000000000..a87b26005 --- /dev/null +++ b/Rectangle/WindowCalculation/BottomRightThirdCalculation.swift @@ -0,0 +1,51 @@ +// +// BottomRightThirdCalculation.swift +// Rectangle +// +// Created by Daniel Schultz on 1/2/22. +// Copyright © 2022 Ryan Hanson. All rights reserved. +// + +import Foundation + +class BottomRightThirdCalculation: WindowCalculation, OrientationAware, HorizontalThirdsRepeated { + + override func calculateRect(_ params: RectCalculationParameters) -> RectResult { + let visibleFrameOfScreen = params.visibleFrameOfScreen + + guard Defaults.subsequentExecutionMode.value != .none, + let last = params.lastAction, + let lastSubAction = last.subAction + else { + return orientationBasedRect(visibleFrameOfScreen) + } + + if last.action != .bottomRightThird { + return orientationBasedRect(visibleFrameOfScreen) + } + + if let calculation = self.nextCalculation(subAction: lastSubAction, direction: .right) { + return calculation(visibleFrameOfScreen) + } + + return orientationBasedRect(visibleFrameOfScreen) + } + + func landscapeRect(_ visibleFrameOfScreen: CGRect) -> RectResult { + var rect = visibleFrameOfScreen + rect.size.width = floor(2.0 * visibleFrameOfScreen.width / 3.0) + rect.size.height = floor(visibleFrameOfScreen.height / 2.0) + rect.origin.y = visibleFrameOfScreen.minY + rect.origin.x = visibleFrameOfScreen.minX + visibleFrameOfScreen.width / 3.0 + return RectResult(rect, subAction: .bottomRightThird) + } + + func portraitRect(_ visibleFrameOfScreen: CGRect) -> RectResult { + var rect = visibleFrameOfScreen + rect.size.width = floor(visibleFrameOfScreen.width / 2.0) + rect.size.height = floor(2.0 * visibleFrameOfScreen.height / 3.0) + rect.origin.y = visibleFrameOfScreen.minY + rect.origin.x = visibleFrameOfScreen.minX + visibleFrameOfScreen.width / 2.0 + return RectResult(rect, subAction: .bottomRightThird) + } +} diff --git a/Rectangle/WindowCalculation/HorizontalThirdsRepeated.swift b/Rectangle/WindowCalculation/HorizontalThirdsRepeated.swift new file mode 100644 index 000000000..ff2f3cd5f --- /dev/null +++ b/Rectangle/WindowCalculation/HorizontalThirdsRepeated.swift @@ -0,0 +1,48 @@ +// +// HorizontalThirdsRepeated.swift +// Rectangle +// +// Created by Daniel Schultz on 1/2/22. +// Copyright © 2022 Ryan Hanson. All rights reserved. +// + +import Foundation + +protocol HorizontalThirdsRepeated { + func nextCalculation(subAction: SubWindowAction, direction: Direction) -> SimpleCalc? +} + +extension HorizontalThirdsRepeated { + func nextCalculation(subAction: SubWindowAction, direction: Direction) -> SimpleCalc? { + + if direction == .left { + switch subAction { + case .topLeftThird: + return WindowCalculationFactory.bottomRightThirdCalculation.orientationBasedRect + case .topRightThird: + return WindowCalculationFactory.topLeftThirdCalculation.orientationBasedRect + case .bottomLeftThird: + return WindowCalculationFactory.topRightThirdCalculation.orientationBasedRect + case .bottomRightThird: + return WindowCalculationFactory.bottomLeftThirdCalculation.orientationBasedRect + default: break + } + } + + else if direction == .right { + switch subAction { + case .topLeftThird: + return WindowCalculationFactory.topRightThirdCalculation.orientationBasedRect + case .topRightThird: + return WindowCalculationFactory.bottomLeftThirdCalculation.orientationBasedRect + case .bottomLeftThird: + return WindowCalculationFactory.bottomRightThirdCalculation.orientationBasedRect + case .bottomRightThird: + return WindowCalculationFactory.topLeftThirdCalculation.orientationBasedRect + default: break + } + } + + return nil + } +} diff --git a/Rectangle/WindowCalculation/TopLeftThirdCalculation.swift b/Rectangle/WindowCalculation/TopLeftThirdCalculation.swift new file mode 100644 index 000000000..a27a59bab --- /dev/null +++ b/Rectangle/WindowCalculation/TopLeftThirdCalculation.swift @@ -0,0 +1,51 @@ +// +// TopLeftThirdCalculation.swift +// Rectangle +// +// Created by Daniel Schultz on 1/2/22. +// Copyright © 2022 Ryan Hanson. All rights reserved. +// + +import Foundation + +class TopLeftThirdCalculation: WindowCalculation, OrientationAware, HorizontalThirdsRepeated { + + override func calculateRect(_ params: RectCalculationParameters) -> RectResult { + let visibleFrameOfScreen = params.visibleFrameOfScreen + + guard Defaults.subsequentExecutionMode.value != .none, + let last = params.lastAction, + let lastSubAction = last.subAction + else { + return orientationBasedRect(visibleFrameOfScreen) + } + + if last.action != .topLeftThird { + return orientationBasedRect(visibleFrameOfScreen) + } + + if let calculation = self.nextCalculation(subAction: lastSubAction, direction: .right) { + return calculation(visibleFrameOfScreen) + } + + return orientationBasedRect(visibleFrameOfScreen) + } + + func landscapeRect(_ visibleFrameOfScreen: CGRect) -> RectResult { + var rect = visibleFrameOfScreen + rect.size.width = floor(2.0 * visibleFrameOfScreen.width / 3.0) + rect.size.height = floor(visibleFrameOfScreen.height / 2.0) + rect.origin.y = visibleFrameOfScreen.minY + visibleFrameOfScreen.height / 2.0 + rect.origin.x = visibleFrameOfScreen.minX + return RectResult(rect, subAction: .topLeftThird) + } + + func portraitRect(_ visibleFrameOfScreen: CGRect) -> RectResult { + var rect = visibleFrameOfScreen + rect.size.width = floor(visibleFrameOfScreen.width / 2.0) + rect.size.height = floor(2.0 * visibleFrameOfScreen.height / 3.0) + rect.origin.y = visibleFrameOfScreen.minY + visibleFrameOfScreen.height / 3.0 + rect.origin.x = visibleFrameOfScreen.minX + return RectResult(rect, subAction: .topLeftThird) + } +} diff --git a/Rectangle/WindowCalculation/TopRightThirdCalculation.swift b/Rectangle/WindowCalculation/TopRightThirdCalculation.swift new file mode 100644 index 000000000..0906bdce1 --- /dev/null +++ b/Rectangle/WindowCalculation/TopRightThirdCalculation.swift @@ -0,0 +1,51 @@ +// +// TopRightThirdCalculation.swift +// Rectangle +// +// Created by Daniel Schultz on 1/2/22. +// Copyright © 2022 Ryan Hanson. All rights reserved. +// + +import Foundation + +class TopRightThirdCalculation: WindowCalculation, OrientationAware, HorizontalThirdsRepeated { + + override func calculateRect(_ params: RectCalculationParameters) -> RectResult { + let visibleFrameOfScreen = params.visibleFrameOfScreen + + guard Defaults.subsequentExecutionMode.value != .none, + let last = params.lastAction, + let lastSubAction = last.subAction + else { + return orientationBasedRect(visibleFrameOfScreen) + } + + if last.action != .topRightThird { + return orientationBasedRect(visibleFrameOfScreen) + } + + if let calculation = self.nextCalculation(subAction: lastSubAction, direction: .right) { + return calculation(visibleFrameOfScreen) + } + + return orientationBasedRect(visibleFrameOfScreen) + } + + func landscapeRect(_ visibleFrameOfScreen: CGRect) -> RectResult { + var rect = visibleFrameOfScreen + rect.size.width = floor(2.0 * visibleFrameOfScreen.width / 3.0) + rect.size.height = floor(visibleFrameOfScreen.height / 2.0) + rect.origin.y = visibleFrameOfScreen.minY + rect.height + rect.origin.x = visibleFrameOfScreen.minX + visibleFrameOfScreen.width / 3.0 + return RectResult(rect, subAction: .topRightThird) + } + + func portraitRect(_ visibleFrameOfScreen: CGRect) -> RectResult { + var rect = visibleFrameOfScreen + rect.size.width = floor(visibleFrameOfScreen.width / 2.0) + rect.size.height = floor(2.0 * visibleFrameOfScreen.height / 3.0) + rect.origin.y = visibleFrameOfScreen.minY + visibleFrameOfScreen.height / 3.0 + rect.origin.x = visibleFrameOfScreen.minX + visibleFrameOfScreen.width / 2.0 + return RectResult(rect, subAction: .topRightThird) + } +} diff --git a/Rectangle/WindowCalculation/WindowCalculation.swift b/Rectangle/WindowCalculation/WindowCalculation.swift index 28cb0cec8..06335e090 100644 --- a/Rectangle/WindowCalculation/WindowCalculation.swift +++ b/Rectangle/WindowCalculation/WindowCalculation.swift @@ -155,6 +155,10 @@ class WindowCalculationFactory { static let bottomLeftNinthCalculation = BottomLeftNinthCalculation() static let bottomCenterNinthCalculation = BottomCenterNinthCalculation() static let bottomRightNinthCalculation = BottomRightNinthCalculation() + static let topLeftThirdCalculation = TopLeftThirdCalculation() + static let topRightThirdCalculation = TopRightThirdCalculation() + static let bottomLeftThirdCalculation = BottomLeftThirdCalculation() + static let bottomRightThirdCalculation = BottomRightThirdCalculation() static let specifiedCalculation = SpecifiedCalculation() static let calculationsByAction: [WindowAction: WindowCalculation] = [ @@ -205,6 +209,10 @@ class WindowCalculationFactory { .bottomLeftNinth: bottomLeftNinthCalculation, .bottomCenterNinth: bottomCenterNinthCalculation, .bottomRightNinth: bottomRightNinthCalculation, + .topLeftThird: topLeftThirdCalculation, + .topRightThird: topRightThirdCalculation, + .bottomLeftThird: bottomLeftThirdCalculation, + .bottomRightThird: bottomRightThirdCalculation, .specified: specifiedCalculation // .restore: nil ] diff --git a/TerminalCommands.md b/TerminalCommands.md index c465b235e..d5d62f207 100644 --- a/TerminalCommands.md +++ b/TerminalCommands.md @@ -122,6 +122,23 @@ For example, the command for setting the top left ninth shortcut to `ctrl opt sh defaults write com.knollsoft.Rectangle topLeftNinth -dict-add keyCode -float 18 modifierFlags -float 917504 ``` +### Add additional "thirds" sizing commands (Available in 0.51) + +These commands for resizing to non-standard screen thirds are not available in the UI but can be configured via CLI. + +The key codes are: + +* topLeftThird +* topRightThird +* bottomLeftThird +* bottomRightThird + +For example, the command for setting the top left third shortcut to `ctrl opt shift 1` would be: + +```bash +defaults write com.knollsoft.Rectangle topLeftThird -dict-add keyCode -float 18 modifierFlags -float 917504 +``` + ## Modify the "footprint" displayed for drag to snap area Adjust the alpha (transparency). Default is 0.3.