mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Refactoring [skip ci]
This commit is contained in:
19
submodules/TelegramUI/Components/MultiScaleTextNode/BUILD
Normal file
19
submodules/TelegramUI/Components/MultiScaleTextNode/BUILD
Normal file
@@ -0,0 +1,19 @@
|
||||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "MultiScaleTextNode",
|
||||
module_name = "MultiScaleTextNode",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/Display",
|
||||
"//submodules/AsyncDisplayKit",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,111 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
|
||||
private final class MultiScaleTextStateNode: ASDisplayNode {
|
||||
let textNode: ImmediateTextNode
|
||||
|
||||
var currentLayout: MultiScaleTextLayout?
|
||||
|
||||
override init() {
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.displaysAsynchronously = false
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.textNode)
|
||||
}
|
||||
}
|
||||
|
||||
public final class MultiScaleTextState {
|
||||
public struct Attributes {
|
||||
public var font: UIFont
|
||||
public var color: UIColor
|
||||
|
||||
public init(font: UIFont, color: UIColor) {
|
||||
self.font = font
|
||||
self.color = color
|
||||
}
|
||||
}
|
||||
|
||||
public let attributes: Attributes
|
||||
public let constrainedSize: CGSize
|
||||
|
||||
public init(attributes: Attributes, constrainedSize: CGSize) {
|
||||
self.attributes = attributes
|
||||
self.constrainedSize = constrainedSize
|
||||
}
|
||||
}
|
||||
|
||||
public struct MultiScaleTextLayout {
|
||||
public var size: CGSize
|
||||
|
||||
public init(size: CGSize) {
|
||||
self.size = size
|
||||
}
|
||||
}
|
||||
|
||||
public final class MultiScaleTextNode: ASDisplayNode {
|
||||
private let stateNodes: [AnyHashable: MultiScaleTextStateNode]
|
||||
|
||||
public init(stateKeys: [AnyHashable]) {
|
||||
self.stateNodes = Dictionary(stateKeys.map { ($0, MultiScaleTextStateNode()) }, uniquingKeysWith: { lhs, _ in lhs })
|
||||
|
||||
super.init()
|
||||
|
||||
for (_, node) in self.stateNodes {
|
||||
self.addSubnode(node)
|
||||
}
|
||||
}
|
||||
|
||||
public func stateNode(forKey key: AnyHashable) -> ASDisplayNode? {
|
||||
return self.stateNodes[key]?.textNode
|
||||
}
|
||||
|
||||
public func updateLayout(text: String, states: [AnyHashable: MultiScaleTextState], mainState: AnyHashable) -> [AnyHashable: MultiScaleTextLayout] {
|
||||
assert(Set(states.keys) == Set(self.stateNodes.keys))
|
||||
assert(states[mainState] != nil)
|
||||
|
||||
var result: [AnyHashable: MultiScaleTextLayout] = [:]
|
||||
var mainLayout: MultiScaleTextLayout?
|
||||
for (key, state) in states {
|
||||
if let node = self.stateNodes[key] {
|
||||
node.textNode.attributedText = NSAttributedString(string: text, font: state.attributes.font, textColor: state.attributes.color)
|
||||
node.textNode.isAccessibilityElement = true
|
||||
node.textNode.accessibilityLabel = text
|
||||
let nodeSize = node.textNode.updateLayout(state.constrainedSize)
|
||||
let nodeLayout = MultiScaleTextLayout(size: nodeSize)
|
||||
if key == mainState {
|
||||
mainLayout = nodeLayout
|
||||
}
|
||||
node.currentLayout = nodeLayout
|
||||
result[key] = nodeLayout
|
||||
}
|
||||
}
|
||||
if let mainLayout = mainLayout {
|
||||
let mainBounds = CGRect(origin: CGPoint(x: -mainLayout.size.width / 2.0, y: -mainLayout.size.height / 2.0), size: mainLayout.size)
|
||||
for (key, _) in states {
|
||||
if let node = self.stateNodes[key], let nodeLayout = result[key] {
|
||||
node.textNode.frame = CGRect(origin: CGPoint(x: mainBounds.minX, y: mainBounds.minY + floor((mainBounds.height - nodeLayout.size.height) / 2.0)), size: nodeLayout.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public func update(stateFractions: [AnyHashable: CGFloat], alpha: CGFloat = 1.0, transition: ContainedViewLayoutTransition) {
|
||||
var fractionSum: CGFloat = 0.0
|
||||
for (_, fraction) in stateFractions {
|
||||
fractionSum += fraction
|
||||
}
|
||||
for (key, fraction) in stateFractions {
|
||||
if let node = self.stateNodes[key], let _ = node.currentLayout {
|
||||
if !transition.isAnimated {
|
||||
node.layer.removeAllAnimations()
|
||||
}
|
||||
transition.updateAlpha(node: node, alpha: fraction / fractionSum * alpha)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user