diff options
Diffstat (limited to 'Hotline/macOS/FilePreviewView.swift')
| -rw-r--r-- | Hotline/macOS/FilePreviewView.swift | 333 |
1 files changed, 0 insertions, 333 deletions
diff --git a/Hotline/macOS/FilePreviewView.swift b/Hotline/macOS/FilePreviewView.swift deleted file mode 100644 index d170dd7..0000000 --- a/Hotline/macOS/FilePreviewView.swift +++ /dev/null @@ -1,333 +0,0 @@ -import SwiftUI - -class FilePreviewWindowController: NSWindowController, NSWindowDelegate { - init(info: PreviewFileInfo) { - let window = PreviewWindow( - contentRect: NSRect(x: 0, y: 0, width: 480, height: 300), - styleMask: [.titled, .unifiedTitleAndToolbar, .closable, .miniaturizable, .resizable, .fullSizeContentView], - backing: .buffered, defer: false) - - super.init(window: window) - - window.toolbarStyle = .unified - window.delegate = self - window.title = info.name - window.acceptsMouseMovedEvents = true - window.appearance = NSAppearance(named: .darkAqua) - window.collectionBehavior = .fullScreenAuxiliary - - window.standardWindowButton(.closeButton)?.isHidden = false - window.standardWindowButton(.miniaturizeButton)?.isHidden = false - window.standardWindowButton(.zoomButton)?.isHidden = false - - window.center() - - let rootView = PreviewWindowView(frame: NSRect(x: 0, y: 0, width: 480, height: 300)) - rootView.autoresizingMask = [.width, .height] - - let hostingView = NSHostingView(rootView: FilePreviewView(info: info)) - hostingView.frame = rootView.bounds - hostingView.autoresizingMask = [.width, .height] - rootView.addSubview(hostingView) - - window.contentView = rootView - -// let toolbar = NSToolbar() -// toolbar.allowsUserCustomization = false -// toolbar.displayMode = .iconOnly -// -// window.toolbar = toolbar - - self.showWindow(nil) - window.makeFirstResponder(nil) - } - - deinit { - print("FilePreviewWindowController: dealloc") - } - - required init?(coder: NSCoder) { - return nil - } -} - -struct FilePreviewToolbar: View { - var body: some View { -// ToolbarItem(placement: .primaryAction) { - Button { - - } label: { - Image(systemName: "plus") - } - .buttonStyle(.accessoryBar) -// } - } -} - -struct FilePreviewView: View { - enum FilePreviewFocus: Hashable { - case window - } - - @Environment(\.controlActiveState) private var controlActiveState - @Environment(\.colorScheme) private var colorScheme - - let info: PreviewFileInfo - - @State var preview: FilePreview? = nil - @Namespace var mainNamespace - @FocusState private var focusField: FilePreviewFocus? - - var body: some View { - Group { - if preview?.state != .loaded { - ProgressView(value: max(0.0, min(1.0, preview?.progress ?? 0.0))) - .focusable(false) - .padding() - .accentColor(colorScheme == .dark ? .white : .black) - .frame(maxWidth: 250) - .focusEffectDisabled() - } - else { - if let img = preview?.image { - AnimatedImageView(image: img) - .focusable(false) - .scaledToFit() - .focusEffectDisabled() - .frame(maxWidth: .infinity, maxHeight: .infinity) - } - else { - Text("UNSUPPORTED FORMAT:") - } - } - } - .focusable() - .focusEffectDisabled() - .focused($focusField, equals: .window) -// .prefersDefaultFocus(in: mainNamespace) -// .focusScope(mainNamespace) -// .focusSection() - - .ignoresSafeArea() - .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(.black) - .overlay(DraggableWindowView()) - .task { - preview = FilePreview(info: info) - preview?.download() - } - .onAppear { - focusField = .window - } - .onDisappear { - preview?.cancel() - } - } -} - -fileprivate struct AnimatedImageView: NSViewRepresentable { - var image: NSImage? - - func aspectFit(source sourceSize: CGSize, bounds boundingSize: CGSize, minimum minSize: CGSize? = nil) -> CGSize { - let sourceAspectRatio = sourceSize.width / sourceSize.height - - var fitSize: CGSize = sourceSize - - if fitSize.width > boundingSize.width { - fitSize.width = boundingSize.width - fitSize.height = fitSize.width / sourceAspectRatio - } - - if fitSize.height > boundingSize.height { - fitSize.height = boundingSize.height - fitSize.width = fitSize.height * sourceAspectRatio - } - - if let m = minSize { - if fitSize.width < m.width { - fitSize.width = m.width - fitSize.height = fitSize.width / sourceAspectRatio - } - - if fitSize.height < m.height { - fitSize.height = m.height - fitSize.width = fitSize.height * sourceAspectRatio - } - } - - return fitSize - } - - func makeNSView(context: Context) -> NSImageView { - let imageView = NSImageView() - imageView.imageScaling = .scaleProportionallyUpOrDown - imageView.animates = true - imageView.isEditable = false - imageView.allowsCutCopyPaste = true - imageView.setContentCompressionResistancePriority(.defaultLow, for: .vertical) - imageView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) - - if let img = self.image { - imageView.image = img - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { - if let window = imageView.window { - window.aspectRatio = img.size - - var windowRect = window.frame - let centerPoint = CGPoint(x: windowRect.midX, y: windowRect.midY) - - windowRect.size = img.size - - if let screen = window.screen { - var paddedScreenSize = screen.frame.size - paddedScreenSize.width *= 0.5 - paddedScreenSize.height *= 0.5 - - window.minSize = aspectFit(source: windowRect.size, bounds: CGSize(width: 400, height: 400)) - windowRect.size = aspectFit(source: windowRect.size, bounds: paddedScreenSize, minimum: window.minSize) - } - - windowRect.origin.x = centerPoint.x - windowRect.width / 2.0 - windowRect.origin.y = centerPoint.y - windowRect.height / 2.0 - - window.setFrame(windowRect, display: true, animate: true) - } - } - } - - return imageView - } - - func updateNSView(_ nsView: NSImageView, context: Context) { - nsView.image = self.image - } -} - -fileprivate struct DraggableWindowView: NSViewRepresentable { - func makeNSView(context: Context) -> NSView { - return DraggableWindowNSView() - } - - func updateNSView(_ nsView: NSView, context: Context) { } -} - -fileprivate class DraggableWindowNSView: NSView { - override public func mouseDown(with event: NSEvent) { - window?.performDrag(with: event) - } -} - -fileprivate class PreviewWindow: NSWindow { - override init(contentRect: NSRect, styleMask style: NSWindow.StyleMask, backing backingStoreType: NSWindow.BackingStoreType, defer flag: Bool) { - super.init(contentRect: contentRect, styleMask: style, backing: backingStoreType, defer: flag) - self.minSize = NSSize(width: 200, height: 200) - self.isReleasedWhenClosed = true - self.titlebarSeparatorStyle = .line - self.acceptsMouseMovedEvents = true - } - - deinit { - print("FilePreviewWindow: dealloc") - } - - override var canBecomeMain: Bool { return true } - override var canBecomeKey: Bool { return true } -} - -fileprivate class PreviewWindowView: NSView { - private var trackingArea: NSTrackingArea? = nil - private var windowIsFullscreen: Bool = false - - override init(frame frameRect: NSRect) { - super.init(frame: frameRect) - - self.updateTrackingAreas() - } - - required init?(coder: NSCoder) { - return nil - } - - deinit { - print("FilePreviewWindowView: dealloc") - } - - override func updateTrackingAreas() { - if let t = self.trackingArea { - self.removeTrackingArea(t) - self.trackingArea = nil - } - - let options: NSTrackingArea.Options = [.mouseEnteredAndExited, .activeAlways] - self.trackingArea = NSTrackingArea(rect: self.bounds, options: options, owner: self, userInfo: nil) - self.addTrackingArea(self.trackingArea!) - } - -// override func viewDidMoveToWindow() { -// print("VIEW MOVED TO WINDOW?") -// if let w = self.window { -//// w.titlebarAppearsTransparent = false -// let toolbarButtons = NSHostingView(rootView: FilePreviewToolbar()) -// toolbarButtons.frame.size = toolbarButtons.fittingSize -// -// let titlebarAccessory = NSTitlebarAccessoryViewController() -// titlebarAccessory.automaticallyAdjustsSize = true -// titlebarAccessory.view = toolbarButtons -// titlebarAccessory.layoutAttribute = .trailing -// w.addTitlebarAccessoryViewController(titlebarAccessory) -// } -// } - - override func mouseEntered(with event: NSEvent) { - if self.windowIsFullscreen { - return - } - - if let w = self.window { - w.titlebarAppearsTransparent = false - w.titleVisibility = .visible - w.standardWindowButton(.closeButton)?.isHidden = false - w.standardWindowButton(.miniaturizeButton)?.isHidden = false - w.standardWindowButton(.zoomButton)?.isHidden = false - w.toolbar?.isVisible = true - } - } - - override func mouseExited(with event: NSEvent) { - if self.windowIsFullscreen { - return - } - - if let w = self.window { - w.titlebarAppearsTransparent = true - w.titleVisibility = .hidden - w.standardWindowButton(.closeButton)?.isHidden = true - w.standardWindowButton(.miniaturizeButton)?.isHidden = true - w.standardWindowButton(.zoomButton)?.isHidden = true - w.toolbar?.isVisible = false - } - } - - func setWindowIsFullscreen(_ isFullscreen: Bool) { - self.windowIsFullscreen = isFullscreen - - if let w = self.window, isFullscreen { - w.titlebarAppearsTransparent = false - w.titleVisibility = .visible - w.standardWindowButton(.closeButton)?.isHidden = false - w.standardWindowButton(.miniaturizeButton)?.isHidden = false - w.standardWindowButton(.zoomButton)?.isHidden = false - } - } - - override var acceptsFirstResponder: Bool { return true } - - override func keyDown(with event: NSEvent) { - switch event.charactersIgnoringModifiers?.first { - case " ": - self.window?.performClose(nil) - default: - break - } - } -} |