diff --git a/Free Ruler/GroupedRulerWindow.swift b/Free Ruler/GroupedRulerWindow.swift index 88dcf98..2ed0e64 100644 --- a/Free Ruler/GroupedRulerWindow.swift +++ b/Free Ruler/GroupedRulerWindow.swift @@ -1693,10 +1693,11 @@ final class RulerManager { defaults: RulerSettings = RulerSettings(defaults: prefs), screenFrame: NSRect = defaultRulerScreenFrame() ) -> GroupedRulerController { - let state = RulerInstanceState.createFromDefaults( + let defaultState = RulerInstanceState.createFromDefaults( defaults: defaults, screenFrame: screenFrame ) + let state = staggeredState(from: defaultState) return addRuler(state: state) } @@ -1793,6 +1794,18 @@ final class RulerManager { } } + private func staggeredState(from defaultState: RulerInstanceState) -> RulerInstanceState { + var state = defaultState + let offset = Ruler.thickness / 2 + + while controllers.contains(where: { $0.state.layout.zeroPoint == state.layout.zeroPoint }) { + state.layout.zeroPoint.x += offset + state.layout.zeroPoint.y -= offset + } + + return state + } + private func notifyStateChanged() { onStateChanged?(self) } diff --git a/FreeRulerTests/RulerCoreTests.swift b/FreeRulerTests/RulerCoreTests.swift index c1a9109..2a6d339 100644 --- a/FreeRulerTests/RulerCoreTests.swift +++ b/FreeRulerTests/RulerCoreTests.swift @@ -169,6 +169,26 @@ final class RulerCoreTests: XCTestCase { XCTAssertEqual(manager.states.map(\.settings.unit), [.inches]) } + func testRulerManagerStaggersNewRulersWhenDefaultPositionIsOccupied() { + let manager = RulerManager() + defer { + for controller in manager.controllers { + controller.hide() + } + } + + let screenFrame = NSRect(x: 0, y: 0, width: 1000, height: 800) + let first = manager.createRuler(screenFrame: screenFrame) + let second = manager.createRuler(screenFrame: screenFrame) + let third = manager.createRuler(screenFrame: screenFrame) + let staggerOffset = Ruler.thickness / 2 + + XCTAssertEqual(second.state.layout.zeroPoint.x, first.state.layout.zeroPoint.x + staggerOffset) + XCTAssertEqual(second.state.layout.zeroPoint.y, first.state.layout.zeroPoint.y - staggerOffset) + XCTAssertEqual(third.state.layout.zeroPoint.x, first.state.layout.zeroPoint.x + (staggerOffset * 2)) + XCTAssertEqual(third.state.layout.zeroPoint.y, first.state.layout.zeroPoint.y - (staggerOffset * 2)) + } + func testRulerContextMenuActivatesClickedRulerAndShowsSettingsCommand() { withInstalledAppDelegate { appDelegate in let manager = appDelegate.rulerManager