2024-05-20 18:51:35 +04:00

129 lines
4.9 KiB
Swift

import Foundation
import UIKit
import Display
import ComponentFlow
import TelegramPresentationData
final class GroupExpandActionButton: UIButton {
override static var layerClass: AnyClass {
return PassthroughLayer.self
}
let tintContainerLayer: SimpleLayer
private var currentTextLayout: (string: String, color: UIColor, constrainedWidth: CGFloat, size: CGSize)?
private let backgroundLayer: SimpleLayer
private let tintBackgroundLayer: SimpleLayer
private let textLayer: SimpleLayer
private let pressed: () -> Void
init(pressed: @escaping () -> Void) {
self.pressed = pressed
self.tintContainerLayer = SimpleLayer()
self.backgroundLayer = SimpleLayer()
self.backgroundLayer.masksToBounds = true
self.tintBackgroundLayer = SimpleLayer()
self.tintBackgroundLayer.masksToBounds = true
self.textLayer = SimpleLayer()
super.init(frame: CGRect())
(self.layer as? PassthroughLayer)?.mirrorLayer = self.tintContainerLayer
self.layer.addSublayer(self.backgroundLayer)
self.layer.addSublayer(self.textLayer)
self.addTarget(self, action: #selector(self.onPressed), for: .touchUpInside)
}
required init(coder: NSCoder) {
preconditionFailure()
}
@objc private func onPressed() {
self.pressed()
}
override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
self.alpha = 0.6
return super.beginTracking(touch, with: event)
}
override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
let alpha = self.alpha
self.alpha = 1.0
self.layer.animateAlpha(from: alpha, to: 1.0, duration: 0.25)
super.endTracking(touch, with: event)
}
override func cancelTracking(with event: UIEvent?) {
let alpha = self.alpha
self.alpha = 1.0
self.layer.animateAlpha(from: alpha, to: 1.0, duration: 0.25)
super.cancelTracking(with: event)
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
let alpha = self.alpha
self.alpha = 1.0
self.layer.animateAlpha(from: alpha, to: 1.0, duration: 0.25)
super.touchesCancelled(touches, with: event)
}
func update(theme: PresentationTheme, title: String, useOpaqueTheme: Bool) -> CGSize {
let textConstrainedWidth: CGFloat = 100.0
let color = theme.list.itemCheckColors.foregroundColor
if useOpaqueTheme {
self.backgroundLayer.backgroundColor = theme.chat.inputMediaPanel.panelContentControlOpaqueOverlayColor.cgColor
} else {
self.backgroundLayer.backgroundColor = theme.chat.inputMediaPanel.panelContentControlVibrantOverlayColor.cgColor
}
self.tintContainerLayer.backgroundColor = UIColor.white.cgColor
let textSize: CGSize
if let currentTextLayout = self.currentTextLayout, currentTextLayout.string == title, currentTextLayout.color == color, currentTextLayout.constrainedWidth == textConstrainedWidth {
textSize = currentTextLayout.size
} else {
let font: UIFont = Font.semibold(13.0)
let string = NSAttributedString(string: title.uppercased(), font: font, textColor: color)
let stringBounds = string.boundingRect(with: CGSize(width: textConstrainedWidth, height: 100.0), options: .usesLineFragmentOrigin, context: nil)
textSize = CGSize(width: ceil(stringBounds.width), height: ceil(stringBounds.height))
self.textLayer.contents = generateImage(textSize, opaque: false, scale: 0.0, rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
UIGraphicsPushContext(context)
string.draw(in: stringBounds)
UIGraphicsPopContext()
})?.cgImage
self.currentTextLayout = (title, color, textConstrainedWidth, textSize)
}
var sideInset: CGFloat = 10.0
if textSize.width > 24.0 {
sideInset = 6.0
}
let size = CGSize(width: textSize.width + sideInset * 2.0, height: 28.0)
let textFrame = CGRect(origin: CGPoint(x: floor((size.width - textSize.width) / 2.0), y: floor((size.height - textSize.height) / 2.0)), size: textSize)
self.textLayer.frame = textFrame
self.backgroundLayer.frame = CGRect(origin: CGPoint(), size: size)
self.tintBackgroundLayer.frame = CGRect(origin: CGPoint(), size: size)
self.backgroundLayer.cornerRadius = min(size.width, size.height) / 2.0
self.tintContainerLayer.cornerRadius = min(size.width, size.height) / 2.0
return size
}
}