Swiftgram/submodules/Display/Source/PeekControllerMenuItemNode.swift
2019-11-14 23:27:44 +04:00

108 lines
4.0 KiB
Swift

import Foundation
import UIKit
import AsyncDisplayKit
public enum PeekControllerMenuItemColor {
case accent
case destructive
}
public enum PeekControllerMenuItemFont {
case `default`
case bold
}
public struct PeekControllerMenuItem {
public let title: String
public let color: PeekControllerMenuItemColor
public let font: PeekControllerMenuItemFont
public let action: (ASDisplayNode, CGRect) -> Bool
public init(title: String, color: PeekControllerMenuItemColor, font: PeekControllerMenuItemFont = .default, action: @escaping (ASDisplayNode, CGRect) -> Bool) {
self.title = title
self.color = color
self.font = font
self.action = action
}
}
final class PeekControllerMenuItemNode: HighlightTrackingButtonNode {
private let item: PeekControllerMenuItem
private let activatedAction: () -> Void
private let separatorNode: ASDisplayNode
private let highlightedBackgroundNode: ASDisplayNode
private let textNode: ImmediateTextNode
init(theme: PeekControllerTheme, item: PeekControllerMenuItem, activatedAction: @escaping () -> Void) {
self.item = item
self.activatedAction = activatedAction
self.separatorNode = ASDisplayNode()
self.separatorNode.isLayerBacked = true
self.separatorNode.backgroundColor = theme.menuItemSeparatorColor
self.highlightedBackgroundNode = ASDisplayNode()
self.highlightedBackgroundNode.isLayerBacked = true
self.highlightedBackgroundNode.backgroundColor = theme.menuItemHighligtedColor
self.highlightedBackgroundNode.alpha = 0.0
self.textNode = ImmediateTextNode()
self.textNode.isUserInteractionEnabled = false
self.textNode.displaysAsynchronously = false
let textColor: UIColor
let textFont: UIFont
switch item.color {
case .accent:
textColor = theme.accentColor
case .destructive:
textColor = theme.destructiveColor
}
switch item.font {
case .default:
textFont = Font.regular(20.0)
case .bold:
textFont = Font.medium(20.0)
}
self.textNode.attributedText = NSAttributedString(string: item.title, font: textFont, textColor: textColor)
super.init()
self.addSubnode(self.separatorNode)
self.addSubnode(self.highlightedBackgroundNode)
self.addSubnode(self.textNode)
self.highligthedChanged = { [weak self] highlighted in
if let strongSelf = self {
if highlighted {
strongSelf.view.superview?.bringSubviewToFront(strongSelf.view)
strongSelf.highlightedBackgroundNode.alpha = 1.0
} else {
strongSelf.highlightedBackgroundNode.alpha = 0.0
strongSelf.highlightedBackgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3)
}
}
}
self.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
}
func updateLayout(width: CGFloat, transition: ContainedViewLayoutTransition) -> CGFloat {
let height: CGFloat = 57.0
transition.updateFrame(node: self.highlightedBackgroundNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: height)))
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: height), size: CGSize(width: width, height: UIScreenPixel)))
let textSize = self.textNode.updateLayout(CGSize(width: width - 10.0, height: height))
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: floor((width - textSize.width) / 2.0), y: floor((height - textSize.height) / 2.0)), size: textSize))
return height
}
@objc func buttonPressed() {
if self.item.action(self, self.bounds) {
self.activatedAction()
}
}
}