Swiftgram/submodules/TelegramUI/Sources/IconButtonNode.swift
2020-12-25 20:16:12 +04:00

98 lines
3.5 KiB
Swift

import Foundation
import UIKit
import AsyncDisplayKit
import Display
private let circleDiameter: CGFloat = 80.0
final class IconButtonNode: HighlightTrackingButtonNode {
private let iconNode: ASImageNode
private var circleNode: ASImageNode?
var icon: UIImage? {
didSet {
self.iconNode.image = self.icon
self.setNeedsLayout()
}
}
var circleColor: UIColor? {
didSet {
if let color = self.circleColor {
let circleNode: ASImageNode
if let current = self.circleNode {
circleNode = current
} else {
circleNode = ASImageNode()
circleNode.alpha = 0.0
circleNode.displaysAsynchronously = false
circleNode.displayWithoutProcessing = true
circleNode.bounds = CGRect(origin: CGPoint(), size: CGSize(width: circleDiameter, height: circleDiameter))
circleNode.position = CGPoint(x: self.frame.width / 2.0, y: self.frame.height / 2.0)
self.insertSubnode(circleNode, at: 0)
self.circleNode = circleNode
}
circleNode.image = generateFilledCircleImage(diameter: circleDiameter, color: color)
} else if let current = self.circleNode {
self.circleNode = nil
current.removeFromSupernode()
}
}
}
override var isEnabled: Bool {
didSet {
self.alpha = self.isEnabled ? 1.0 : 0.4
}
}
var isPressing = false {
didSet {
if self.isPressing != oldValue && !self.isPressing {
self.highligthedChanged(false)
}
}
}
init() {
self.iconNode = ASImageNode()
self.iconNode.isLayerBacked = true
self.iconNode.displaysAsynchronously = false
self.iconNode.displayWithoutProcessing = true
super.init(pointerStyle: .circle)
self.addSubnode(self.iconNode)
self.highligthedChanged = { [weak self] highlighted in
if let strongSelf = self {
if highlighted {
let transition: ContainedViewLayoutTransition = .animated(duration: 0.18, curve: .linear)
transition.updateSublayerTransformScale(node: strongSelf, scale: 0.8)
if let circleNode = strongSelf.circleNode {
transition.updateAlpha(node: circleNode, alpha: 1.0)
}
} else if !strongSelf.isPressing {
let transition: ContainedViewLayoutTransition = .animated(duration: 0.35, curve: .linear)
transition.updateSublayerTransformScale(node: strongSelf, scale: 1.0)
if let circleNode = strongSelf.circleNode {
transition.updateAlpha(node: circleNode, alpha: 0.0)
}
}
}
}
}
override func layout() {
super.layout()
let size = self.bounds.size
if let image = self.iconNode.image {
self.iconNode.frame = CGRect(origin: CGPoint(x: floor((size.width - image.size.width) / 2.0), y: floor((size.height - image.size.height) / 2.0)), size: image.size)
}
self.circleNode?.position = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
}
}