1 Commits
Author SHA1 Message Date
Ivan Sapozhnik f39f238846 Handling arrow position 2020-04-04 22:51:02 +02:00
3 changed files with 39 additions and 21 deletions
+10
View File
@@ -8,6 +8,11 @@
import Cocoa
class PopoverWindow: NSPanel {
var arrowXLocation: CGFloat = 0.0 {
didSet {
updateArrowPosition()
}
}
private let wConfig: PopoverConfiguration
private var childContentView: NSView?
private var backgroundView: PopoverWindowBackgroundView?
@@ -90,4 +95,9 @@ class PopoverWindow: NSPanel {
override func frameRect(forContentRect contentRect: NSRect) -> NSRect {
NSMakeRect(NSMinX(contentRect), NSMinY(contentRect), NSWidth(contentRect), NSHeight(contentRect) + wConfig.arrowHeight)
}
private func updateArrowPosition() {
guard let backgroundView = self.backgroundView as? PopoverWindowBackgroundView else { return }
backgroundView.arrowXLocation = arrowXLocation
}
}
@@ -9,6 +9,11 @@ import Cocoa
class PopoverWindowBackgroundView: NSView {
private let wConfig: PopoverConfiguration
var arrowXLocation: CGFloat = 0.0 {
didSet {
needsDisplay = true
}
}
init(frame frameRect: NSRect, windowConfiguration: PopoverConfiguration) {
self.wConfig = windowConfiguration
@@ -35,13 +40,14 @@ class PopoverWindowBackgroundView: NSView {
let arrowPath = NSBezierPath()
let backgroundPath = NSBezierPath(roundedRect: backgroundRect, xRadius: wConfig.cornerRadius, yRadius: wConfig.cornerRadius)
let leftPoint = NSPoint(x: NSWidth(backgroundRect) / 2 - wConfig.arrowWidth / 2, y: NSMaxY(backgroundRect))
let toPoint = NSPoint(x: NSWidth(backgroundRect) / 2, y: NSMaxY(backgroundRect) + wConfig.arrowHeight)
let rightPoint = NSPoint(x: NSWidth(backgroundRect) / 2 + wConfig.arrowWidth / 2, y: NSMaxY(backgroundRect))
let cp11 = NSPoint(x: NSWidth(backgroundRect) / 2 - wConfig.arrowWidth / 6, y: NSMaxY(backgroundRect))
let cp12 = NSPoint(x: NSWidth(backgroundRect) / 2 - wConfig.arrowWidth / 9, y: NSMaxY(backgroundRect) + wConfig.arrowHeight)
let cp21 = NSPoint(x: NSWidth(backgroundRect) / 2 + wConfig.arrowWidth / 9, y: NSMaxY(backgroundRect) + wConfig.arrowHeight)
let cp22 = NSPoint(x: NSWidth(backgroundRect) / 2 + wConfig.arrowWidth / 6, y: NSMaxY(backgroundRect))
let x = arrowXLocation
let leftPoint = NSPoint(x: x - wConfig.arrowWidth / 2, y: NSMaxY(backgroundRect))
let toPoint = NSPoint(x: x, y: NSMaxY(backgroundRect) + wConfig.arrowHeight)
let rightPoint = NSPoint(x: x + wConfig.arrowWidth / 2, y: NSMaxY(backgroundRect))
let cp11 = NSPoint(x: x - wConfig.arrowWidth / 6, y: NSMaxY(backgroundRect))
let cp12 = NSPoint(x: x - wConfig.arrowWidth / 9, y: NSMaxY(backgroundRect) + wConfig.arrowHeight)
let cp21 = NSPoint(x: x + wConfig.arrowWidth / 9, y: NSMaxY(backgroundRect) + wConfig.arrowHeight)
let cp22 = NSPoint(x: x + wConfig.arrowWidth / 6, y: NSMaxY(backgroundRect))
controlPoints.append(NSBezierPath(ovalIn: NSMakeRect(leftPoint.x - 2, leftPoint.y - 2, 4, 4)))
controlPoints.append(NSBezierPath(ovalIn: NSMakeRect(toPoint.x - 2, toPoint.y - 2, 4, 4)))
@@ -70,8 +76,8 @@ class PopoverWindowBackgroundView: NSView {
wConfig.backgroundColor.setFill()
windowPath.fill()
// NSColor.red.setFill()
// controlPoints.fill()
}
override var frame: NSRect {
+15 -13
View File
@@ -46,27 +46,29 @@ class PopoverWindowController: NSWindowController {
}
private func updateWindowFrame() {
guard let window = self.window as? PopoverWindow else { return }
let windowFrame = visibleStatusItemWindowFrame()
window?.setFrame(windowFrame, display: true)
window?.appearance = NSAppearance.current
window.arrowXLocation = windowFrame.arrowXLocation
window.setFrame(windowFrame.frame, display: true)
window.appearance = NSAppearance.current
}
private func visibleStatusItemWindowFrame() -> NSRect {
private func visibleStatusItemWindowFrame() -> (frame: NSRect, arrowXLocation: CGFloat) {
let screenFrame = currentMouseScreen().frame
let popoverRect = popover.item.button?.window?.frame ?? .zero
let statusItemRect = popover.item.button?.window?.frame ?? .zero
guard let window = self.window else { return .zero }
guard let window = self.window else { return (.zero, 0.0) }
let rightEdgeMargin: CGFloat = 5.0
let borderWidth = wConfig.borderColor != nil ? wConfig.borderWidth : 0
let x = NSMinX(popoverRect) - NSWidth(window.frame) / 2 + NSWidth(popoverRect) / 2 + borderWidth
let y = min(NSMinY(popoverRect), NSMaxY(screenFrame)) - NSHeight(window.frame) - wConfig.popoverToStatusItemMargin + borderWidth / 2
let x = min(NSMinX(statusItemRect) - NSWidth(window.frame) / 2 + NSWidth(statusItemRect) / 2 + borderWidth, NSMaxX(screenFrame) - NSWidth(window.frame) - rightEdgeMargin)
let y = min(NSMinY(statusItemRect), NSMaxY(screenFrame)) - NSHeight(window.frame) - wConfig.popoverToStatusItemMargin + borderWidth / 2
return NSMakeRect(
x,
y,
NSWidth(window.frame),
NSHeight(window.frame)
)
let windowFrame = NSMakeRect(x, y, NSWidth(window.frame), NSHeight(window.frame))
let arrowXLocation = NSMinX(statusItemRect) + NSWidth(statusItemRect) / 2 - NSMinX(windowFrame)
return (windowFrame, arrowXLocation)
}
private func currentMouseScreen() -> NSScreen {