Swiftgram/submodules/InstantPageUI/Sources/InstantPageSettingsItemNode.swift

127 lines
5.6 KiB
Swift

import Foundation
import UIKit
import AsyncDisplayKit
import Display
enum InstantPageSettingsItemNodeStatus {
case none
case sameSection
case otherSection
}
class InstantPageSettingsItemNode: ASDisplayNode {
private let topSeparatorNode: ASDisplayNode
private let bottomSeparatorNode: ASDisplayNode
private let highlightedBackgroundNode: ASDisplayNode?
private let highlightButtonNode: HighlightTrackingButtonNode?
init(theme: InstantPageSettingsItemTheme, selectable: Bool) {
self.topSeparatorNode = ASDisplayNode()
self.topSeparatorNode.isLayerBacked = true
self.topSeparatorNode.isHidden = true
self.bottomSeparatorNode = ASDisplayNode()
self.bottomSeparatorNode.isLayerBacked = true
self.bottomSeparatorNode.isHidden = true
if selectable {
let highlightedBackgroundNode = ASDisplayNode()
highlightedBackgroundNode.isLayerBacked = true
highlightedBackgroundNode.alpha = 0.0
self.highlightedBackgroundNode = highlightedBackgroundNode
self.highlightButtonNode = HighlightTrackingButtonNode()
} else {
self.highlightedBackgroundNode = nil
self.highlightButtonNode = nil
}
super.init()
self.backgroundColor = theme.itemBackgroundColor
self.addSubnode(self.topSeparatorNode)
self.addSubnode(self.bottomSeparatorNode)
if let highlightedBackgroundNode = self.highlightedBackgroundNode {
self.addSubnode(highlightedBackgroundNode)
}
if let highlightButtonNode = self.highlightButtonNode {
self.addSubnode(highlightButtonNode)
highlightButtonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
highlightButtonNode.highligthedChanged = { [weak self] highlighted in
if let strongSelf = self, let highlightedBackgroundNode = strongSelf.highlightedBackgroundNode {
if highlighted {
strongSelf.supernode?.view.bringSubviewToFront(strongSelf.view)
highlightedBackgroundNode.layer.removeAnimation(forKey: "opacity")
highlightedBackgroundNode.alpha = 1.0
} else {
highlightedBackgroundNode.alpha = 0.0
highlightedBackgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
}
}
}
}
self.updateTheme(theme)
}
func updateTheme(_ theme: InstantPageSettingsItemTheme) {
self.backgroundColor = theme.itemBackgroundColor
self.highlightedBackgroundNode?.backgroundColor = theme.itemHighlightedBackgroundColor
self.topSeparatorNode.backgroundColor = theme.separatorColor
self.bottomSeparatorNode.backgroundColor = theme.separatorColor
}
func updateInternalLayout(width: CGFloat, insets: UIEdgeInsets, previousItem: (InstantPageSettingsItemNodeStatus, InstantPageSettingsItemNode?), nextItem: (InstantPageSettingsItemNodeStatus, InstantPageSettingsItemNode?)) -> (height: CGFloat, separatorInset: CGFloat?) {
return (44.0 + insets.top + insets.bottom, nil)
}
final func updateLayout(width: CGFloat, previousItem: (InstantPageSettingsItemNodeStatus, InstantPageSettingsItemNode?), nextItem: (InstantPageSettingsItemNodeStatus, InstantPageSettingsItemNode?)) -> CGFloat {
let separatorHeight = UIScreenPixel
let separatorInset: CGFloat = 0.0
var highlightExtension: CGFloat = 0.0
switch previousItem.0 {
case .none:
self.topSeparatorNode.isHidden = true
case .sameSection:
self.topSeparatorNode.isHidden = false
case .otherSection:
self.topSeparatorNode.isHidden = false
}
switch nextItem.0 {
case .none:
self.bottomSeparatorNode.isHidden = true
case .sameSection:
self.bottomSeparatorNode.isHidden = true
highlightExtension = separatorHeight
case .otherSection:
self.bottomSeparatorNode.isHidden = false
}
let (internalHeight, internalSeparatorInset) = self.updateInternalLayout(width: width, insets: UIEdgeInsets(top: self.topSeparatorNode.isHidden ? 0.0 : separatorHeight, left: 0.0, bottom: self.bottomSeparatorNode.isHidden ? 0.0 : separatorHeight, right: 0.0), previousItem: previousItem, nextItem: nextItem)
let finalSeparatorInset = internalSeparatorInset ?? separatorInset
self.topSeparatorNode.frame = CGRect(origin: CGPoint(x: finalSeparatorInset, y: 0.0), size: CGSize(width: width - finalSeparatorInset, height: separatorHeight))
self.bottomSeparatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: internalHeight - separatorHeight), size: CGSize(width: width, height: separatorHeight))
if let highlightButtonNode = self.highlightButtonNode {
highlightButtonNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -highlightExtension), size: CGSize(width: width, height: internalHeight + highlightExtension))
}
if let highlightedBackgroundNode = self.highlightedBackgroundNode {
highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: width, height: internalHeight + highlightExtension))
}
return internalHeight
}
@objc func buttonPressed() {
self.pressed()
}
func pressed() {
}
}