// // KMToolbarCustomItemView.swift // PDF Reader Pro // // Created by tangchao on 2024/6/4. // import Cocoa class KMToolbarCustomItemView: KMToolbarItemView { private var menuViewC_: KMCustomButtonPopMenuViewController? private var popOver_: NSPopover? var popOver: NSPopover? { get { return self.popOver_ } set { if self.popOver_ == nil || self.popOver_!.isEqual(to: newValue) == false { self.popOver_ = newValue if (newValue != nil) { self.layer?.backgroundColor = Self.selectedBackgroundColor.cgColor } else { self.updateSelectBackground() } } } } convenience init(itemIdentifier: String, postition imagePosition: NSControl.ImagePosition, withPopMenu popMenuViewController: KMCustomButtonPopMenuViewController?) { self.init(itemIdentifier: itemIdentifier) self.boxImagePosition = imagePosition self.menuViewC_ = popMenuViewController // if (popMenuViewController != nil) { NotificationCenter.default.addObserver(self, selector: #selector(_windowClosedPop), name: KMToolbarItemView.popOverClosedNotificationName, object: nil) // } } override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) // Drawing code here. } override func mouseEntered(with event: NSEvent) { super.mouseEntered(with: event) guard let _window = self.window else { return } if (!_window.isKeyWindow) { return } if (self.itemIdentifier == KMToolbarDividerItemIdentifier || self.customizeView != nil || self.image == nil) { return } if self.unEnabled { return } if self.isPopToolTip { self._showPopTip(self) }else { if (self.needExpandAction) { self.needExpandButton.image = NSImage(named: "KMImageNameUXIconBtnTriDownNor") self._showPop(self) }else if (self.isShowCustomToolTip) { self.perform(#selector(_showHUDHint), with: nil, afterDelay: 0.1) } } } override func mouseExited(with event: NSEvent) { super.mouseExited(with: event) if(self.needExpandAction && !self.isSelected) { self.needExpandButton.image = NSImage(named: "KMImageNameUXIconBtnTriDownNor") } guard let _window = self.window else { return } if (!_window.isKeyWindow) { return } if(self.nameBtn.superview != nil && !self.isSelected) { self.nameBtn.setTitleColor(color: Self.fetchTextNormalColor()) } if self.isPopToolTip { NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(_showHUDHint), object: nil) self._closePop() }else{ if (self.isShowCustomToolTip && !self.needExpandAction) { NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(_showHUDHint), object: nil) self._closePop() } } } // MARK: - Popover private func _showPop(_ sender: NSView) { if (self.popOver_ != nil) { return } let menuViewController = KMCustomButtonPopMenuViewController() menuViewController.delegate = self menuViewController.dataSources = self self.popOver = NSPopover() self.popOver?.delegate = self self.popOver?.contentViewController = menuViewController self.popOver?.animates = false self.popOver?.behavior = .semitransient self.popOver?.contentSize = menuViewController.view.frame.size var sourcesRect = sender.bounds sourcesRect = sender.convert(sourcesRect, to: nil) sourcesRect.origin.y -= 20 sourcesRect.size.height += 20 self.window?.popover = self.popOver self.window?.sourcesRect = sourcesRect self.popOver?.show(relativeTo: CGRectInset(self.bounds, 0, 5), of: self, preferredEdge: .minY) } func _showPopTip(_ sender: NSView) { if (self.popOver_ != nil) { return } let popViewController = KMToolbarItemPopViewController() self.popOver = NSPopover() self.popOver?.contentViewController = popViewController self.popOver?.animates = false self.popOver?.behavior = .semitransient self.popOver?.contentSize = popViewController.view.frame.size popViewController.updateWithHelpTip(helpTip: self.toolTip ?? "") self.popOver?.show(relativeTo: CGRectInset(self.bounds, 0, 5), of: self, preferredEdge: .minY) } private func _closePop() { self.popOver?.close() self.popOver = nil } @objc private func _showHUDHint() { // KMToolbarItemPopViewController *popViewController = [[[KMToolbarItemPopViewController alloc] init] autorelease]; // self.popOver = [[[NSPopover alloc] init] autorelease]; // self.popOver.contentViewController = popViewController; // self.popOver.animates = NO; // self.popOver.behavior = NSPopoverBehaviorSemitransient; // self.popOver.backgroundColor = [KMAppearance KMBluegrey01Color]; // // self.popOver.contentSize = popViewController.view.frame.size; // [popViewController updateWithHelpTip:self.originalHelpTip]; // [self.popOver showRelativeToRect:self.bounds ofView:self preferredEdge:NSRectEdgeMinY]; } @objc private func _windowClosedPop(sender: Notification) { if let data = self.popOver_?.isEqual(to: sender.object), data { self.popOver = nil } } } extension KMToolbarCustomItemView: NSPopoverDelegate { func popoverDidClose(_ notification: Notification) { if let data = self.popOver?.isEqual(to: notification.object), data { self._closePop() } } } extension KMToolbarCustomItemView: KMCustomButtonPopMenuViewControllerDelegate, KMCustomButtonPopMenuViewControllerDataSources { func customViewButtonPopDidSelectIndex(_ index: Int) { self._closePop() if let items = self.menuFormRepresentation?.submenu?.items { let item = items[index] _ = item.target?.perform(item.action, with: item) } } func numberOfLine() -> Int { if let items = self.menuFormRepresentation?.submenu?.items { return items.count } return 0 } func stringForLine(at index: Int) -> String? { if let items = self.menuFormRepresentation?.submenu?.items { return items[index].title } return nil } func needInsertSeperateLine(at index: Int) -> Bool { if let items = self.menuFormRepresentation?.submenu?.items { return items[index].isSeparatorItem } return false } func needHightLightLine(at index: Int) -> Bool { return false } func imageForLine(at index: Int) -> NSImage? { if let items = self.menuFormRepresentation?.submenu?.items { return items[index].image } return nil } func itemEnable(at index: Int) -> Bool { if self.itemIdentifier == KMToolbarToolFormAlignIdentifier { if index <= 6 { if let cnt = self.pdfView?.activeAnnotations.count, cnt >= 2 { return true } } else { if let cnt = self.pdfView?.activeAnnotations.count, cnt >= 3 { return true } } return false } return true } }