Improve resizing with draggable and hotkeys
This commit is contained in:
@@ -4,6 +4,10 @@ import Combine
|
||||
/// Per-screen observable state that drives the notch UI.
|
||||
@MainActor
|
||||
class NotchViewModel: ObservableObject {
|
||||
private static let minimumOpenWidth: CGFloat = 320
|
||||
private static let minimumOpenHeight: CGFloat = 140
|
||||
private static let windowHorizontalPadding: CGFloat = 40
|
||||
private static let windowVerticalPadding: CGFloat = 20
|
||||
|
||||
let screenUUID: String
|
||||
|
||||
@@ -13,6 +17,7 @@ class NotchViewModel: ObservableObject {
|
||||
@Published var isHovering: Bool = false
|
||||
@Published var isCloseTransitionActive: Bool = false
|
||||
@Published var suppressHoverOpenUntilHoverExit: Bool = false
|
||||
@Published var isUserResizing: Bool = false
|
||||
|
||||
let terminalManager = TerminalManager.shared
|
||||
|
||||
@@ -20,6 +25,7 @@ class NotchViewModel: ObservableObject {
|
||||
/// window activation so the terminal receives keyboard input.
|
||||
var requestOpen: (() -> Void)?
|
||||
var requestClose: (() -> Void)?
|
||||
var requestWindowResize: (() -> Void)?
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
@@ -49,7 +55,10 @@ class NotchViewModel: ObservableObject {
|
||||
}
|
||||
|
||||
func open() {
|
||||
notchSize = CGSize(width: openWidth, height: openHeight)
|
||||
let size = openNotchSize
|
||||
openWidth = size.width
|
||||
openHeight = size.height
|
||||
notchSize = size
|
||||
notchState = .open
|
||||
}
|
||||
|
||||
@@ -65,7 +74,58 @@ class NotchViewModel: ObservableObject {
|
||||
}
|
||||
|
||||
var openNotchSize: CGSize {
|
||||
CGSize(width: openWidth, height: openHeight)
|
||||
clampedOpenSize(CGSize(width: openWidth, height: openHeight))
|
||||
}
|
||||
|
||||
func beginInteractiveResize() {
|
||||
isUserResizing = true
|
||||
}
|
||||
|
||||
func resizeOpenNotch(to proposedSize: CGSize) {
|
||||
setOpenSize(proposedSize, notifyWindowResize: true)
|
||||
}
|
||||
|
||||
func endInteractiveResize() {
|
||||
isUserResizing = false
|
||||
}
|
||||
|
||||
func applySizePreset(_ preset: TerminalSizePreset, notifyWindowResize: Bool = true) {
|
||||
setOpenSize(preset.size, notifyWindowResize: notifyWindowResize)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func setOpenSize(_ proposedSize: CGSize, notifyWindowResize: Bool) -> CGSize {
|
||||
let clampedSize = clampedOpenSize(proposedSize)
|
||||
openWidth = clampedSize.width
|
||||
openHeight = clampedSize.height
|
||||
if notchState == .open {
|
||||
notchSize = clampedSize
|
||||
}
|
||||
if notifyWindowResize {
|
||||
requestWindowResize?()
|
||||
}
|
||||
return clampedSize
|
||||
}
|
||||
|
||||
private func clampedOpenSize(_ size: CGSize) -> CGSize {
|
||||
CGSize(
|
||||
width: size.width.clamped(to: Self.minimumOpenWidth...maximumAllowedWidth),
|
||||
height: size.height.clamped(to: Self.minimumOpenHeight...maximumAllowedHeight)
|
||||
)
|
||||
}
|
||||
|
||||
private var maximumAllowedWidth: CGFloat {
|
||||
guard let screen = NSScreen.screens.first(where: { $0.displayUUID == screenUUID }) ?? NSScreen.main else {
|
||||
return Self.minimumOpenWidth
|
||||
}
|
||||
return max(Self.minimumOpenWidth, screen.frame.width - Self.windowHorizontalPadding)
|
||||
}
|
||||
|
||||
private var maximumAllowedHeight: CGFloat {
|
||||
guard let screen = NSScreen.screens.first(where: { $0.displayUUID == screenUUID }) ?? NSScreen.main else {
|
||||
return Self.minimumOpenHeight
|
||||
}
|
||||
return max(Self.minimumOpenHeight, screen.frame.height - Self.windowVerticalPadding)
|
||||
}
|
||||
|
||||
var closeInteractionLockDuration: TimeInterval {
|
||||
@@ -102,3 +162,9 @@ class NotchViewModel: ObservableObject {
|
||||
closeTransitionTask?.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
private extension CGFloat {
|
||||
func clamped(to range: ClosedRange<CGFloat>) -> CGFloat {
|
||||
Swift.min(Swift.max(self, range.lowerBound), range.upperBound)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user