You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

334 lines
11 KiB

// Copyright © 2015 Abhishek Banthia
import Cocoa
class PanelController: ParentPanelController {
var hasActivePanel: Bool = false
static var sharedWindow = PanelController(windowNibName: .panel)
@IBOutlet var backgroundView: BackgroundPanelView!
override func windowDidLoad() {
super.windowDidLoad()
}
@objc class func shared() -> PanelController {
return sharedWindow
}
override func awakeFromNib() {
super.awakeFromNib()
window?.title = "Clocker Panel"
window?.setAccessibilityIdentifier("Clocker Panel")
futureSlider.isContinuous = true
if let panel = window {
panel.acceptsMouseMovedEvents = true
panel.level = .popUpMenu
panel.isOpaque = false
panel.backgroundColor = NSColor.clear
}
mainTableView.registerForDraggedTypes([.dragSession])
super.updatePanelColor()
super.updateDefaultPreferences()
}
@objc override func updateDefaultPreferences() {
super.updateDefaultPreferences()
}
6 years ago
func setFrameTheNewWay(_ rect: NSRect, _ maxX: CGFloat) {
// Calculate window's top left point.
// First, center window under status item.
let w = CGFloat(NSWidth((window?.frame)!))
6 years ago
var x = CGFloat(roundf(Float(rect.midX - w / 2)))
let y = CGFloat(rect.minY - 2)
let kMinimumSpaceBetweenWindowAndScreenEdge: CGFloat = 10
if x + w + kMinimumSpaceBetweenWindowAndScreenEdge > maxX {
x = maxX - w - kMinimumSpaceBetweenWindowAndScreenEdge
}
6 years ago
window?.setFrameTopLeftPoint(NSPoint(x: x, y: y))
window?.invalidateShadow()
}
func open() {
guard isWindowLoaded == true else {
return
}
super.dismissRowActions()
updateDefaultPreferences()
futureSlider.integerValue = 0
sliderDatePicker.dateValue = Date()
setTimezoneDatasourceSlider(sliderValue: 0)
reviewView.isHidden = !(RateController.canPrompt())
reviewView.layer?.backgroundColor = NSColor.clear.cgColor
setPanelFrame()
startWindowTimer()
if DataStore.shared().shouldDisplay(ViewType.upcomingEventView) {
retrieveCalendarEvents()
} else {
removeUpcomingEventView()
super.setScrollViewConstraint()
}
// This is done to make the UI look updated.
mainTableView.reloadData()
log()
}
// New way to set the panel's frame.
// This takes into account the screen's dimensions.
private func setPanelFrame() {
6 years ago
guard let appDelegate = NSApplication.shared.delegate as? AppDelegate else {
return
}
6 years ago
var statusBackgroundWindow = appDelegate.statusItemForPanel().statusItem.view?.window
var statusView = appDelegate.statusItemForPanel().statusItem.view
6 years ago
// This below is a better way than actually checking if the menubar compact mode is set.
if statusBackgroundWindow == nil || statusView == nil {
statusBackgroundWindow = appDelegate.statusItemForPanel().statusItem.button?.window
statusView = appDelegate.statusItemForPanel().statusItem.button
}
6 years ago
if let statusWindow = statusBackgroundWindow,
let statusButton = statusView {
var statusItemFrame = statusWindow.convertToScreen(statusButton.frame)
var statusItemScreen = NSScreen.main
var testPoint = statusItemFrame.origin
testPoint.y -= 100
for screen in NSScreen.screens {
if NSPointInRect(testPoint, screen.frame) {
statusItemScreen = screen
break
}
}
let screenMaxX = NSMaxX((statusItemScreen?.frame)!)
let minY = statusItemFrame.origin.y < NSMaxY((statusItemScreen?.frame)!) ? statusItemFrame.origin.y : NSMaxY((statusItemScreen?.frame)!)
statusItemFrame.origin.y = minY
setFrameTheNewWay(statusItemFrame, screenMaxX)
}
}
private func log() {
let preferences = DataStore.shared().timezones()
guard let theme = DataStore.shared().retrieve(key: CLThemeKey) as? NSNumber,
let displayFutureSliderKey = DataStore.shared().retrieve(key: CLThemeKey) as? NSNumber,
let showAppInForeground = DataStore.shared().retrieve(key: CLShowAppInForeground) as? NSNumber,
let relativeDateKey = DataStore.shared().retrieve(key: CLRelativeDateKey) as? NSNumber,
let showSecondsInMenubar = DataStore.shared().retrieve(key: CLShowSecondsInMenubar) as? NSNumber,
let fontSize = DataStore.shared().retrieve(key: CLUserFontSizePreference) as? NSNumber,
let sunriseTime = DataStore.shared().retrieve(key: CLSunriseSunsetTime) as? NSNumber,
let showDayInMenu = DataStore.shared().retrieve(key: CLShowDayInMenu) as? NSNumber,
let showDateInMenu = DataStore.shared().retrieve(key: CLShowDateInMenu) as? NSNumber,
let showPlaceInMenu = DataStore.shared().retrieve(key: CLShowPlaceInMenu) as? NSNumber,
let showUpcomingEventView = DataStore.shared().retrieve(key: CLShowUpcomingEventView) as? String,
let country = Locale.autoupdatingCurrent.regionCode else {
return
}
var relativeDate = "Relative"
if relativeDateKey.isEqual(to: NSNumber(value: 1)) {
relativeDate = "Actual Day"
} else if relativeDateKey.isEqual(to: NSNumber(value: 2)) {
relativeDate = "Date"
}
let panelEvent: [String: Any] = [
"Theme": theme.isEqual(to: NSNumber(value: 0)) ? "Default" : "Black",
"Display Future Slider": displayFutureSliderKey.isEqual(to: NSNumber(value: 0)) ? "Yes" : "No",
"Clocker mode": showAppInForeground.isEqual(to: NSNumber(value: 0)) ? "Menubar" : "Floating",
"Relative Date": relativeDate,
"Show Seconds in Menubar": showSecondsInMenubar.isEqual(to: NSNumber(value: 0)) ? "Yes" : "No",
"Font Size": fontSize,
"Sunrise Sunset": sunriseTime.isEqual(to: NSNumber(value: 0)) ? "Yes" : "No",
"Show Day in Menu": showDayInMenu.isEqual(to: NSNumber(value: 0)) ? "Yes" : "No",
"Show Date in Menu": showDateInMenu.isEqual(to: NSNumber(value: 0)) ? "Yes" : "No",
"Show Place in Menu": showPlaceInMenu.isEqual(to: NSNumber(value: 0)) ? "Yes" : "No",
"Show Upcoming Event View": showUpcomingEventView == "YES" ? "Yes" : "No",
"Country": country,
"Calendar Access Provided": EventCenter.sharedCenter().calendarAccessGranted() ? "Yes" : "No",
6 years ago
"Number of Timezones": preferences.count
]
Logger.log(object: panelEvent, for: "openedPanel")
}
private func startWindowTimer() {
6 years ago
stopMenubarTimerIfNeccesary()
6 years ago
if let timer = parentTimer, timer.state == .paused {
parentTimer?.start()
return
}
startTimer()
}
private func startTimer() {
6 years ago
print("Start timer called")
6 years ago
parentTimer = Repeater(interval: .seconds(1), mode: .infinite) { _ in
OperationQueue.main.addOperation {
self.updateTime()
}
}
parentTimer!.start()
}
6 years ago
private func stopMenubarTimerIfNeccesary() {
let count = (DataStore.shared().retrieve(key: CLMenubarFavorites) as? [Data])?.count ?? 0
6 years ago
if count >= 1 || DataStore.shared().shouldDisplay(.showMeetingInMenubar) {
if let delegate = NSApplication.shared.delegate as? AppDelegate {
print("\nWe will be invalidating the menubar timer as we want the parent timer to take care of both panel and menubar ")
6 years ago
delegate.invalidateMenubarTimer(false)
}
}
}
func cancelOperation() {
setActivePanel(newValue: false)
}
@objc func hasActivePanelGetter() -> Bool {
return hasActivePanel
}
func minimize() {
let delegate = NSApplication.shared.delegate as? AppDelegate
let count = (DataStore.shared().retrieve(key: CLMenubarFavorites) as? [Data])?.count ?? 0
if count >= 1 || DataStore.shared().shouldDisplay(.showMeetingInMenubar) == true {
if let handler = delegate?.statusItemForPanel(), let timer = handler.menubarTimer, !timer.isValid {
delegate?.setupMenubarTimer()
}
}
parentTimer?.pause()
updatePopoverDisplayState()
NSAnimationContext.beginGrouping()
NSAnimationContext.current.duration = 0.1
window?.animator().alphaValue = 0
morePopover?.close()
NSAnimationContext.endGrouping()
window?.orderOut(nil)
datasource = nil
}
@objc func setActivePanel(newValue: Bool) {
hasActivePanel = newValue
hasActivePanel ? open() : minimize()
}
class func panel() -> PanelController? {
let panel = NSApplication.shared.windows.compactMap { (window) -> PanelController? in
guard let parent = window.windowController as? PanelController else {
return nil
}
return parent
}
return panel.first
}
override func showNotesPopover(forRow row: Int, relativeTo positioningRect: NSRect, andButton target: NSButton!) -> Bool {
guard let popover = morePopover else {
return false
}
target.image = Themer.shared().extraOptionsHighlightedImage()
if popover.isShown && row == previousPopoverRow {
popover.close()
target.image = Themer.shared().extraOptionsImage()
previousPopoverRow = -1
return false
}
previousPopoverRow = row
super.showNotesPopover(forRow: row, relativeTo: positioningRect, andButton: target)
popover.show(relativeTo: positioningRect,
of: target,
preferredEdge: .minX)
if let timer = parentTimer, timer.state == .paused {
timer.start()
}
return true
}
func setupMenubarTimer() {
if let appDelegate = NSApplication.shared.delegate as? AppDelegate {
appDelegate.setupMenubarTimer()
}
}
func pauseTimer() {
if let timer = parentTimer {
timer.pause()
}
}
func refreshBackgroundView() {
backgroundView.setNeedsDisplay(backgroundView.bounds)
}
}
extension PanelController: NSWindowDelegate {
func windowWillClose(_: Notification) {
parentTimer = nil
setActivePanel(newValue: false)
}
func windowDidResignKey(_: Notification) {
if let isVisible = window?.isVisible, isVisible == true {
setActivePanel(newValue: false)
}
if let appDelegate = NSApplication.shared.delegate as? AppDelegate {
appDelegate.statusItemForPanel().hasActiveIcon = false
}
}
}