Files

212 lines
6.1 KiB
Swift

//
// DragController.swift
// Telegram-Mac
//
// Created by keepcoder on 30/10/2016.
// Copyright © 2016 Telegram. All rights reserved.
//
import Cocoa
public class DragItem {
let title:String
let desc:String
let handler:()->Void
let attr:NSAttributedString
public init(title:String, desc:String,handler:@escaping()->Void) {
self.title = title
self.desc = desc
self.handler = handler
let attr:NSMutableAttributedString = NSMutableAttributedString()
_ = attr.append(string: title, color: presentation.colors.grayText, font: .normal(.huge))
_ = attr.append(string: "\n")
_ = attr.append(string: desc, color: presentation.colors.text, font: .medium(16.0))
self.attr = attr.copy() as! NSAttributedString
}
}
class DragView : OverlayControl {
var item:DragItem
var textView:TextView = TextView()
init(item:DragItem) {
self.item = item
super.init(frame: NSZeroRect)
addSubview(textView)
textView.backgroundColor = presentation.colors.background
self.layer?.cornerRadius = .cornerRadius
self.layer?.borderWidth = 2.0
self.layer?.backgroundColor = presentation.colors.background.cgColor
self.layer?.borderColor = presentation.colors.border.cgColor
self.backgroundColor = presentation.colors.background
// self.set(handler: { control in
// control.layer?.borderColor = presentation.colors.accent.cgColor
// control.layer?.animateBorder()
// }, for: .Hover)
//
// self.set(handler: { control in
// control.layer?.borderColor = presentation.colors.border.cgColor
// control.layer?.animateBorder()
// }, for: .Normal)
}
public override func acceptsFirstMouse(for event: NSEvent?) -> Bool {
return true
}
override func layout() {
super.layout()
let layout:TextViewLayout = TextViewLayout(item.attr, maximumNumberOfLines: 2, truncationType: .middle, alignment:.center)
layout.measure(width: frame.width - 20)
textView.update(layout)
textView.center()
}
override func setFrameSize(_ newSize: NSSize) {
super.setFrameSize(newSize)
}
required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
required public init(frame frameRect: NSRect) {
fatalError("init(frame:) has not been implemented")
}
}
public class DraggingView: SplitView {
var container:Control = Control()
public weak var controller:ViewController?
required public init(frame frameRect: NSRect) {
super.init(frame: frameRect)
container.backgroundColor = .clear
self.registerForDraggedTypes([.string, .tiff, .kUrl, .kFilenames])
}
public override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()
}
deinit {
self.unregisterDraggedTypes()
}
override public func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
for itemView in container.subviews as! [DragView] {
if itemView.mouseInside() {
itemView.item.handler()
return true
}
}
return false
}
func layoutItems(with items:[DragItem]) {
container.removeAllSubviews()
let itemSize = NSMakeSize(frame.width - 10, ceil((frame.height - 10 - (5 * (CGFloat(items.count) - 1))) / CGFloat(items.count)))
var y:CGFloat = 5
for item in items {
let view:DragView = DragView(item:item)
view.frame = NSMakeRect(5, y, itemSize.width, itemSize.height)
container.addSubview(view)
y += itemSize.height + 5
}
}
public override func acceptsFirstMouse(for event: NSEvent?) -> Bool {
return true
}
private func updateItems() {
for itemView in container.subviews as! [DragView] {
if itemView.mouseInside() {
itemView.layer?.borderColor = presentation.colors.accent.cgColor
itemView.layer?.animateBorder()
} else {
itemView.layer?.borderColor = presentation.colors.border.cgColor
itemView.layer?.animateBorder()
}
}
}
public override func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation {
updateItems()
return .copy
}
override public func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
if let items = controller?.draggingItems(for: sender.draggingPasteboard), items.count > 0, !sender.draggingSourceOperationMask.isEmpty {
container.frame = bounds
if container.superview == nil {
layoutItems(with: items)
addSubview(container)
}
container.layer?.removeAllAnimations()
container.layer?.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
controller?.draggingEntered()
updateItems()
}
return .copy
}
override public func draggingExited(_ sender: NSDraggingInfo?) {
controller?.draggingExited()
container.layer?.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion:false, completion:{[weak self] (completed) in
if completed {
self?.container.removeFromSuperview()
}
})
}
public override func draggingEnded(_ sender: NSDraggingInfo?) {
draggingExited(sender)
}
public var _hitTest:((NSPoint)->NSView?)?
public override func hitTest(_ point: NSPoint) -> NSView? {
if isEventLess {
return _hitTest?(point)
} else {
return super.hitTest(point)
}
}
required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}