Files
phbar/Sources/phbar/Models/PHTheme/PHThemeWindow/PHThemeWindowAnchor.swift
T
2026-07-12 15:06:51 +02:00

65 lines
2.0 KiB
Swift

import CoreGraphics
import Foundation
/// Where a window is placed within its screen.
///
/// Single-edge anchors (`top`, `bottom`, `leading`, `trailing`) pin to that
/// edge and center along the opposite axis. Corner anchors pin to two edges.
/// `center` centers the window on both axes.
enum PHThemeWindowAnchor: String, Decodable {
case top, bottom, leading, trailing
case topLeading = "top-leading"
case topTrailing = "top-trailing"
case bottomLeading = "bottom-leading"
case bottomTrailing = "bottom-trailing"
case center
}
extension PHThemeWindowAnchor {
/// Compute the top-left origin (in screen coordinates) of a window of `size`
/// placed against this anchor within `screen`, offset by `margin` along the
/// anchored edges.
///
/// Edges the anchor does not reference are ignored, so margins only affect
/// the relevant sides.
func origin(in screen: CGRect, size: CGSize, margin: PHThemeWindowMargin) -> CGPoint {
let top = margin.top ?? 0
let bottom = margin.bottom ?? 0
let leading = margin.leading ?? 0
let trailing = margin.trailing ?? 0
// Default: centered on both axes.
var point = CGPoint(
x: screen.midX - size.width / 2,
y: screen.midY - size.height / 2
)
switch self {
case .top:
point.y = screen.maxY - CGFloat(top) - size.height
case .bottom:
point.y = screen.minY + CGFloat(bottom)
case .leading:
point.x = screen.minX + CGFloat(leading)
case .trailing:
point.x = screen.maxX - CGFloat(trailing) - size.width
case .topLeading:
point.x = screen.minX + CGFloat(leading)
point.y = screen.maxY - CGFloat(top) - size.height
case .topTrailing:
point.x = screen.maxX - CGFloat(trailing) - size.width
point.y = screen.maxY - CGFloat(top) - size.height
case .bottomLeading:
point.x = screen.minX + CGFloat(leading)
point.y = screen.minY + CGFloat(bottom)
case .bottomTrailing:
point.x = screen.maxX - CGFloat(trailing) - size.width
point.y = screen.minY + CGFloat(bottom)
case .center:
break
}
return point
}
}