Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 35 additions & 10 deletions Free Ruler/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,18 @@ class AppDelegate: NSObject, NSApplicationDelegate {
lazy var rulerManager: RulerManager = {
let manager = RulerManager()
manager.onActiveControllerChanged = { [weak self] controller in
self?.groupedRulerController = controller
guard let self = self else { return }

self.groupedRulerController = controller

guard let settingsController = self.rulerSettingsController,
settingsController.window?.isVisible == true else { return }

if let controller = controller {
settingsController.show(attachedTo: controller, sender: self)
} else {
settingsController.close()
}
}
return manager
}()
Expand Down Expand Up @@ -93,6 +104,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var alignRulersMenuItem: NSMenuItem!

var preferencesController: PreferencesController? = nil
var rulerSettingsController: RulerSettingsController? = nil
private let hotkeyBezel = HotkeyBezel()
private var uiTestSupport: UITestSupport?
private var interfaceStyleObserver: NSObjectProtocol?
Expand Down Expand Up @@ -271,14 +283,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
observers = [
prefs.observe(\Prefs.unit, options: .new) { prefs, changed in
self.updateUnitMenu()
self.redrawRulers()
self.redrawDefaultBackedRulers()
self.uiTestSupport?.writePreferencesState()
},
prefs.observe(\Prefs.floatRulers, options: .new) { prefs, changed in
self.updateFloatRulersMenuItem()
for controller in self.rulerManager.controllers {
controller.updateIsFloatingPanel()
}
self.legacyGroupedRulerController?.updateIsFloatingPanel()
self.uiTestSupport?.writePreferencesState()
},
Expand All @@ -289,17 +298,14 @@ class AppDelegate: NSObject, NSApplicationDelegate {
},
prefs.observe(\Prefs.rulerShadow, options: .new) { prefs, changed in
self.updateRulerShadowMenuItem()
for controller in self.rulerManager.controllers {
controller.updateHasShadow()
}
self.legacyGroupedRulerController?.updateHasShadow()
self.uiTestSupport?.writePreferencesState()
},
prefs.observe(\Prefs.rulerColor, options: .new) { prefs, changed in
self.redrawRulers()
self.redrawDefaultBackedRulers()
},
prefs.observe(\Prefs.zeroCorner, options: .new) { prefs, changed in
self.redrawRulers()
self.redrawDefaultBackedRulers()
},
]
}
Expand Down Expand Up @@ -327,6 +333,13 @@ class AppDelegate: NSObject, NSApplicationDelegate {
legacyGroupedRulerController?.redrawForPreferenceChange()
}

func redrawDefaultBackedRulers() {
for ruler in rulers {
ruler.rulerWindow.rule.redrawForPreferenceChange()
}
legacyGroupedRulerController?.redrawForPreferenceChange()
}

func updateFloatRulersMenuItem() {
floatRulersMenuItem?.state = prefs.floatRulers ? .on : .off
}
Expand Down Expand Up @@ -662,6 +675,16 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
}

@IBAction func openRulerSettings(_ sender: Any) {
guard let controller = rulerManager.activeController else { return }

if rulerSettingsController == nil {
rulerSettingsController = RulerSettingsController(rulerController: controller)
}

rulerSettingsController?.show(attachedTo: controller, sender: sender)
}

@IBAction func newRuler(_ sender: Any) {
let controller = rulerManager.createRuler()
controller.show()
Expand Down Expand Up @@ -983,6 +1006,8 @@ extension AppDelegate: NSMenuItemValidation {
switch menuItem.action {
case #selector(newRuler(_:)):
return true
case #selector(openRulerSettings(_:)):
return rulerManager.activeController != nil
case #selector(closeKeyWindow(_:)):
return NSApp.keyWindow?.isVisible == true
case #selector(toggleGroupRulers(_:)):
Expand Down
6 changes: 6 additions & 0 deletions Free Ruler/Base.lproj/MainMenu.xib
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@
<action selector="showRulers:" target="Voe-Tx-rLC" id="NLA-hk-Wbc"/>
</connections>
</menuItem>
<menuItem title="Ruler Settings…" id="rSt-Tg-232">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="openRulerSettings:" target="Voe-Tx-rLC" id="RSa-Tg-232"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
Expand Down
89 changes: 65 additions & 24 deletions Free Ruler/GroupedRulerWindow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,10 @@ final class GroupedRulerWindow: NSPanel {
let verticalRule: VerticalRule

private let groupedContentView: GroupedRulerContentView
private(set) var settings: RulerSettings

init(frame: NSRect) {
init(frame: NSRect, settings: RulerSettings = RulerSettings(defaults: prefs)) {
self.settings = settings
horizontalRule = GroupedHorizontalRule(
frame: NSRect(x: 0, y: 0, width: 300, height: Ruler.thickness)
)
Expand All @@ -294,22 +296,22 @@ final class GroupedRulerWindow: NSPanel {
defer: false
)

alphaValue = windowAlphaValue(prefs.foregroundOpacity)
alphaValue = windowAlphaValue(settings.foregroundOpacity)
title = NSLocalizedString(
"Ruler",
comment: "Window title for a ruler window"
)
identifier = NSUserInterfaceItemIdentifier("grouped-ruler-window")
setAccessibilityIdentifier("grouped-ruler-window")
minSize = GroupedRulerLayout.minSize(zeroCorner: prefs.zeroCorner)
maxSize = GroupedRulerLayout.maxSize(zeroCorner: prefs.zeroCorner)
minSize = GroupedRulerLayout.minSize(zeroCorner: settings.zeroCorner)
maxSize = GroupedRulerLayout.maxSize(zeroCorner: settings.zeroCorner)

isOpaque = false
backgroundColor = .clear
isFloatingPanel = prefs.floatRulers
isFloatingPanel = settings.floatRulers
hidesOnDeactivate = false
isMovableByWindowBackground = true
hasShadow = prefs.rulerShadow
hasShadow = settings.rulerShadow

horizontalRule.setAccessibilityElement(true)
verticalRule.setAccessibilityElement(true)
Expand All @@ -320,6 +322,7 @@ final class GroupedRulerWindow: NSPanel {
groupedContentView.nextResponder = self

contentView = groupedContentView
apply(settings: settings)
updateLayoutForCurrentZeroCorner()
}

Expand Down Expand Up @@ -371,12 +374,23 @@ final class GroupedRulerWindow: NSPanel {
func updateLayoutForCurrentZeroCorner() {
updateSizeConstraintsForVisibleRules()
updateGroupedContentFrame()
groupedContentView.zeroCorner = prefs.zeroCorner
groupedContentView.zeroCorner = settings.zeroCorner
groupedContentView.needsLayout = true
groupedContentView.layoutSubtreeIfNeeded()
groupedContentView.needsDisplay = true
}

func apply(settings: RulerSettings) {
self.settings = settings
alphaValue = windowAlphaValue(settings.foregroundOpacity)
isFloatingPanel = settings.floatRulers
hasShadow = settings.rulerShadow
horizontalRule.settingsOverride = settings
verticalRule.settingsOverride = settings
groupedContentView.color = RulerColors(customFill: settings.rulerColor)
updateLayoutForCurrentZeroCorner()
}

func redrawForPreferenceChange() {
updateLayoutForCurrentZeroCorner()
horizontalRule.redrawForPreferenceChange()
Expand Down Expand Up @@ -417,7 +431,7 @@ final class GroupedRulerWindow: NSPanel {
}

func zeroPoint() -> NSPoint {
let geometry = ZeroCornerGeometry(zeroCorner: prefs.zeroCorner)
let geometry = ZeroCornerGeometry(zeroCorner: settings.zeroCorner)

if isRuleVisible(.horizontal) {
return geometry.zeroPoint(
Expand Down Expand Up @@ -450,12 +464,12 @@ final class GroupedRulerWindow: NSPanel {

private func updateSizeConstraintsForVisibleRules() {
minSize = GroupedRulerLayout.minSize(
zeroCorner: prefs.zeroCorner,
zeroCorner: settings.zeroCorner,
showsHorizontalRule: groupedContentView.showsHorizontalRule,
showsVerticalRule: groupedContentView.showsVerticalRule
)
maxSize = GroupedRulerLayout.maxSize(
zeroCorner: prefs.zeroCorner,
zeroCorner: settings.zeroCorner,
showsHorizontalRule: groupedContentView.showsHorizontalRule,
showsVerticalRule: groupedContentView.showsVerticalRule
)
Expand Down Expand Up @@ -1076,6 +1090,7 @@ final class GroupedRulerController: NSWindowController, NSWindowDelegate, Notifi
private var keyListener: Any?
private var mouseInteraction: RulerMouseInteractionState!
private var isMouseTickDrawingEnabled = true
private let followsDefaultPreferences: Bool

var isLeftMouseButtonPressed = {
return NSEvent.pressedMouseButtons & 1 == 1
Expand All @@ -1085,12 +1100,12 @@ final class GroupedRulerController: NSWindowController, NSWindowDelegate, Notifi
didSet {
updateIsFloatingPanel()
if !preferencesWindowOpen {
opacity = prefs.foregroundOpacity
opacity = state.settings.foregroundOpacity
}
}
}

var opacity = prefs.foregroundOpacity {
var opacity = 0 {
didSet {
groupedWindow.alphaValue = windowAlphaValue(opacity)
}
Expand All @@ -1107,20 +1122,27 @@ final class GroupedRulerController: NSWindowController, NSWindowDelegate, Notifi
)
)

self.init(state: state)
self.init(state: state, followsDefaultPreferences: true)
}

convenience init(state: RulerInstanceState) {
self.init(state: state, followsDefaultPreferences: false)
}

init(state: RulerInstanceState) {
private init(state: RulerInstanceState, followsDefaultPreferences: Bool) {
self.state = state
self.followsDefaultPreferences = followsDefaultPreferences
let layout = state.layout.layout(zeroCorner: state.settings.zeroCorner)
groupedWindow = GroupedRulerWindow(
frame: layout.visibleFrame(
showsHorizontalRule: state.visibility.showsHorizontal,
showsVerticalRule: state.visibility.showsVertical
)
),
settings: state.settings
)
super.init(window: groupedWindow)

opacity = state.settings.foregroundOpacity
createObservers()
subscribeToPrefs()

Expand Down Expand Up @@ -1216,7 +1238,7 @@ final class GroupedRulerController: NSWindowController, NSWindowDelegate, Notifi
horizontalLength: horizontalLength,
verticalLength: verticalLength,
zeroPoint: point,
zeroCorner: prefs.zeroCorner
zeroCorner: state.settings.zeroCorner
)

groupedWindow.setFrame(groupedWindow.visibleFrame(in: layout), display: true)
Expand All @@ -1235,31 +1257,41 @@ final class GroupedRulerController: NSWindowController, NSWindowDelegate, Notifi
zeroCorner: zeroCorner
)

groupedWindow.setFrame(groupedWindow.visibleFrame(in: layout), display: true)
state.settings.zeroCorner = zeroCorner
groupedWindow.apply(settings: state.settings)
groupedWindow.alphaValue = windowAlphaValue(opacity)
updateIsFloatingPanel()
updateHasShadow()
groupedWindow.setFrame(groupedWindow.visibleFrame(in: layout), display: true)
captureStateFromWindow()
}

func foreground() {
opacity = prefs.foregroundOpacity
opacity = state.settings.foregroundOpacity
}

func background() {
opacity = prefs.backgroundOpacity
opacity = state.settings.backgroundOpacity
}

func updateIsFloatingPanel() {
groupedWindow.isFloatingPanel = preferencesWindowOpen ? false : prefs.floatRulers
groupedWindow.isFloatingPanel = preferencesWindowOpen ? false : state.settings.floatRulers
}

func updateHasShadow() {
groupedWindow.hasShadow = prefs.rulerShadow
groupedWindow.hasShadow = state.settings.rulerShadow
}

func redrawForPreferenceChange() {
groupedWindow.redrawForPreferenceChange()
}

func updateSettings(_ update: (inout RulerSettings) -> Void) {
update(&state.settings)
applyStateToWindow(display: true)
notifyStateChanged()
}

func drawMouseTick(at mouseLoc: NSPoint) {
if groupedWindow.isRuleVisible(.horizontal) {
groupedWindow.horizontalRule.drawMouseTick(at: mouseLoc)
Expand All @@ -1284,6 +1316,10 @@ final class GroupedRulerController: NSWindowController, NSWindowDelegate, Notifi
private func applyStateToWindow(display: Bool) {
let zeroCorner = state.settings.zeroCorner
let layout = state.layout.layout(zeroCorner: zeroCorner)
groupedWindow.apply(settings: state.settings)
groupedWindow.alphaValue = windowAlphaValue(opacity)
updateIsFloatingPanel()
updateHasShadow()
groupedWindow.setVisibleRules(
horizontal: state.visibility.showsHorizontal,
vertical: state.visibility.showsVertical
Expand Down Expand Up @@ -1341,7 +1377,7 @@ final class GroupedRulerController: NSWindowController, NSWindowDelegate, Notifi
)
case (true, false):
let horizontalFrame = groupedWindow.screenFrame(for: .horizontal)
let zeroPoint = ZeroCornerGeometry(zeroCorner: prefs.zeroCorner)
let zeroPoint = ZeroCornerGeometry(zeroCorner: state.settings.zeroCorner)
.zeroPoint(in: horizontalFrame, for: .horizontal)
return (
horizontalFrame,
Expand All @@ -1353,7 +1389,7 @@ final class GroupedRulerController: NSWindowController, NSWindowDelegate, Notifi
)
case (false, true):
let verticalFrame = groupedWindow.screenFrame(for: .vertical)
let zeroPoint = ZeroCornerGeometry(zeroCorner: prefs.zeroCorner)
let zeroPoint = ZeroCornerGeometry(zeroCorner: state.settings.zeroCorner)
.zeroPoint(in: verticalFrame, for: .vertical)
return (
hiddenRuleFrame(
Expand All @@ -1373,7 +1409,7 @@ final class GroupedRulerController: NSWindowController, NSWindowDelegate, Notifi
zeroPoint: NSPoint,
size: NSSize
) -> NSRect {
return ZeroCornerGeometry(zeroCorner: prefs.zeroCorner).frame(
return ZeroCornerGeometry(zeroCorner: state.settings.zeroCorner).frame(
for: orientation,
zeroPoint: zeroPoint,
size: size
Expand Down Expand Up @@ -1497,6 +1533,11 @@ final class GroupedRulerController: NSWindowController, NSWindowDelegate, Notifi
}

private func subscribeToPrefs() {
guard followsDefaultPreferences else {
observers = []
return
}

observers = [
prefs.observe(\Prefs.foregroundOpacity, options: .new) { [weak self] prefs, changed in
self?.opacity = prefs.foregroundOpacity
Expand Down
Loading