diff --git a/Rectangle/Snapping/CompoundSnapArea/CompoundSnapArea.swift b/Rectangle/Snapping/CompoundSnapArea/CompoundSnapArea.swift index 0ad89fce..ddd02f35 100644 --- a/Rectangle/Snapping/CompoundSnapArea/CompoundSnapArea.swift +++ b/Rectangle/Snapping/CompoundSnapArea/CompoundSnapArea.swift @@ -10,9 +10,9 @@ import Foundation enum CompoundSnapArea: Int, Codable { - case leftTopBottomHalf = -2, rightTopBottomHalf = -3, thirds = -4, portraitThirdsSide = -5, halves = -6, topSixths = -7, bottomSixths = -8, fourths = -9 + case leftTopBottomHalf = -2, rightTopBottomHalf = -3, thirds = -4, portraitThirdsSide = -5, halves = -6, topSixths = -7, bottomSixths = -8, fourths = -9, portraitTopBottomHalves = -10 - static let all = [leftTopBottomHalf, rightTopBottomHalf, thirds, portraitThirdsSide, halves, topSixths, bottomSixths, fourths] + static let all = [leftTopBottomHalf, rightTopBottomHalf, thirds, portraitThirdsSide, halves, topSixths, bottomSixths, fourths, portraitTopBottomHalves] static let leftCompoundCalculation = LeftTopBottomHalfCalculation() static let rightCompoundCalculation = RightTopBottomHalfCalculation() @@ -22,6 +22,7 @@ enum CompoundSnapArea: Int, Codable { static let topSixthsCalculation = TopSixthsCompoundCalculation() static let bottomSixthsCalculation = BottomSixthsCompoundCalculation() static let fourthsColumnCalculation = FourthsColumnCompoundCalculation() + static let portraitTopBottomCalculation = TopBottomHalvesCalculation() var displayName: String { switch self { @@ -41,6 +42,8 @@ enum CompoundSnapArea: Int, Codable { return NSLocalizedString("Bottom sixths from corners; thirds", tableName: "Main", value: "", comment: "") case .fourths: return NSLocalizedString("Fourths columns", tableName: "Main", value: "", comment: "") + case .portraitTopBottomHalves: + return NSLocalizedString("Top/bottom halves", tableName: "Main", value: "", comment: "") } } @@ -62,6 +65,8 @@ enum CompoundSnapArea: Int, Codable { return Self.bottomSixthsCalculation case .fourths: return Self.fourthsColumnCalculation + case .portraitTopBottomHalves: + return Self.portraitTopBottomCalculation } } @@ -83,6 +88,8 @@ enum CompoundSnapArea: Int, Codable { return [.b] case .fourths: return [.t, .b] + case .portraitTopBottomHalves: + return [.l, .r] } } @@ -90,7 +97,7 @@ enum CompoundSnapArea: Int, Codable { switch self { case .leftTopBottomHalf, .rightTopBottomHalf, .halves: return [.portrait, .landscape] - case .portraitThirdsSide: + case .portraitThirdsSide, .portraitTopBottomHalves: return [.portrait] case .thirds, .topSixths, .bottomSixths, .fourths: return [.landscape] diff --git a/Rectangle/Snapping/CompoundSnapArea/HalvesCompoundCalculation.swift b/Rectangle/Snapping/CompoundSnapArea/HalvesCompoundCalculation.swift index 388707aa..791eabbb 100644 --- a/Rectangle/Snapping/CompoundSnapArea/HalvesCompoundCalculation.swift +++ b/Rectangle/Snapping/CompoundSnapArea/HalvesCompoundCalculation.swift @@ -69,3 +69,39 @@ struct LeftRightHalvesCompoundCalculation: CompoundSnapAreaCalculation { } } + +struct TopBottomHalvesCalculation: CompoundSnapAreaCalculation { + private let marginTop = Defaults.snapEdgeMarginTop.cgFloat + private let marginBottom = Defaults.snapEdgeMarginBottom.cgFloat + private let ignoredSnapAreas = SnapAreaOption(rawValue: Defaults.ignoredSnapAreas.value) + + func snapArea(cursorLocation loc: NSPoint, screen: NSScreen, directional: Directional, priorSnapArea: SnapArea?) -> SnapArea? { + let frame = screen.frame + let halfHeight = floor(frame.height / 2) + let shortEdgeSize = Defaults.shortEdgeSnapAreaSize.cgFloat + + if loc.y <= frame.minY + marginBottom + shortEdgeSize { + let snapAreaOption: SnapAreaOption = loc.x < frame.midX ? .bottomLeftShort : .bottomRightShort + if !ignoredSnapAreas.contains(snapAreaOption) { + return SnapArea(screen: screen, directional: directional, action: .bottomHalf) + } + } + + if loc.y >= frame.maxY - marginTop - shortEdgeSize { + let snapAreaOption: SnapAreaOption = loc.x < frame.midX ? .topLeftShort : .topRightShort + if !ignoredSnapAreas.contains(snapAreaOption) { + return SnapArea(screen: screen, directional: directional, action: .topHalf) + } + } + + if loc.y >= frame.minY && loc.y <= frame.minY + halfHeight { + return SnapArea(screen: screen, directional: directional, action: .bottomHalf) + } + + if loc.y > frame.minY + halfHeight && loc.y <= frame.maxY { + return SnapArea(screen: screen, directional: directional, action: .topHalf) + } + + return nil + } +} diff --git a/Rectangle/mul.lproj/Main.xcstrings b/Rectangle/mul.lproj/Main.xcstrings index 2050e202..4a4d9756 100644 --- a/Rectangle/mul.lproj/Main.xcstrings +++ b/Rectangle/mul.lproj/Main.xcstrings @@ -16207,7 +16207,24 @@ "state" : "translated", "value" : "⋯" } + } + } + }, + "Extra Shortcuts" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Extra Shortcuts" + } }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Дополнительные горячие клавиши" + } + } } }, "F2S-fz-NVQ.title" : { @@ -16768,23 +16785,6 @@ } } }, - "Extra Shortcuts" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Extra Shortcuts" - } - }, - "ru" : { - "stringUnit" : { - "state" : "translated", - "value" : "Дополнительные горячие клавиши" - } - }, - } - }, "F12-EV-Lfz.title" : { "comment" : "Class = \"NSTextFieldCell\"; title = \"First Third\"; ObjectID = \"F12-EV-Lfz\";", "extractionState" : "extracted_with_value", @@ -27579,7 +27579,7 @@ "state" : "translated", "value" : "Увеличить ширину" } - }, + } } }, "Lbh-J2-qVU.title" : { @@ -39233,7 +39233,7 @@ "state" : "translated", "value" : "Уменьшить ширину" } - }, + } } }, "snW-S8-Cw5.title" : { @@ -41417,6 +41417,17 @@ } } }, + "Top/bottom halves" : { + "extractionState" : "manual", + "localizations" : { + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Górna/Dolna połowa" + } + } + } + }, "tRr-pd-1PS.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Data Detectors\"; ObjectID = \"tRr-pd-1PS\";", "extractionState" : "manual", @@ -46071,7 +46082,7 @@ "state" : "translated", "value" : "Шаг ширины (px)" } - }, + } } }, "wpr-3q-Mcd.title" : { @@ -50144,4 +50155,4 @@ } }, "version" : "1.0" -} +} \ No newline at end of file