mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-28 16:42:20 +00:00
Added volume control icon
This commit is contained in:
parent
bb44454500
commit
b3419d2af5
@ -76,7 +76,22 @@ final class VolumeControlStatusBar: UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final class VolumeControlStatusBarNode: ASDisplayNode {
|
final class VolumeControlStatusBarNode: ASDisplayNode {
|
||||||
|
var innerGraphics: (UIImage, UIImage, UIImage, Bool)?
|
||||||
|
var graphics: (UIImage, UIImage, UIImage)? = nil {
|
||||||
|
didSet {
|
||||||
|
if self.isDark {
|
||||||
|
self.innerGraphics = generateDarkGraphics(self.graphics)
|
||||||
|
} else {
|
||||||
|
if let graphics = self.graphics {
|
||||||
|
self.innerGraphics = (graphics.0, graphics.1, graphics.2, false)
|
||||||
|
} else {
|
||||||
|
self.innerGraphics = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private let backgroundNode: ASImageNode
|
private let backgroundNode: ASImageNode
|
||||||
|
private let iconNode: ASImageNode
|
||||||
private let foregroundNode: ASImageNode
|
private let foregroundNode: ASImageNode
|
||||||
private let foregroundClippingNode: ASDisplayNode
|
private let foregroundClippingNode: ASDisplayNode
|
||||||
|
|
||||||
@ -88,9 +103,15 @@ final class VolumeControlStatusBarNode: ASDisplayNode {
|
|||||||
if self.isDark {
|
if self.isDark {
|
||||||
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: UIColor(white: 0.6, alpha: 1.0))
|
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: UIColor(white: 0.6, alpha: 1.0))
|
||||||
self.foregroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: .white)
|
self.foregroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: .white)
|
||||||
|
|
||||||
|
self.innerGraphics = generateDarkGraphics(self.graphics)
|
||||||
} else {
|
} else {
|
||||||
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: UIColor(white: 0.6, alpha: 1.0))
|
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: UIColor(rgb: 0xc5c5c5))
|
||||||
self.foregroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: .black)
|
self.foregroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: .black)
|
||||||
|
|
||||||
|
if let graphics = self.graphics {
|
||||||
|
self.innerGraphics = (graphics.0, graphics.1, graphics.2, false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,7 +123,7 @@ final class VolumeControlStatusBarNode: ASDisplayNode {
|
|||||||
self.backgroundNode.isLayerBacked = true
|
self.backgroundNode.isLayerBacked = true
|
||||||
self.backgroundNode.displaysAsynchronously = false
|
self.backgroundNode.displaysAsynchronously = false
|
||||||
self.backgroundNode.displayWithoutProcessing = true
|
self.backgroundNode.displayWithoutProcessing = true
|
||||||
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: .gray)
|
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: UIColor(rgb: 0xc5c5c5))
|
||||||
|
|
||||||
self.foregroundNode = ASImageNode()
|
self.foregroundNode = ASImageNode()
|
||||||
self.foregroundNode.isLayerBacked = true
|
self.foregroundNode.isLayerBacked = true
|
||||||
@ -114,22 +135,49 @@ final class VolumeControlStatusBarNode: ASDisplayNode {
|
|||||||
self.foregroundClippingNode.clipsToBounds = true
|
self.foregroundClippingNode.clipsToBounds = true
|
||||||
self.foregroundClippingNode.addSubnode(self.foregroundNode)
|
self.foregroundClippingNode.addSubnode(self.foregroundNode)
|
||||||
|
|
||||||
|
self.iconNode = ASImageNode()
|
||||||
|
self.iconNode.isLayerBacked = true
|
||||||
|
self.iconNode.displaysAsynchronously = false
|
||||||
|
self.iconNode.displayWithoutProcessing = true
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.isUserInteractionEnabled = false
|
self.isUserInteractionEnabled = false
|
||||||
|
|
||||||
self.addSubnode(self.backgroundNode)
|
self.addSubnode(self.backgroundNode)
|
||||||
self.addSubnode(self.foregroundClippingNode)
|
self.addSubnode(self.foregroundClippingNode)
|
||||||
|
self.addSubnode(self.iconNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateDarkGraphics(_ graphics: (UIImage, UIImage, UIImage)?) -> (UIImage, UIImage, UIImage, Bool)? {
|
||||||
|
if var (offImage, halfImage, onImage) = graphics {
|
||||||
|
offImage = generateTintedImage(image: offImage, color: UIColor.black)!
|
||||||
|
halfImage = generateTintedImage(image: halfImage, color: UIColor.black)!
|
||||||
|
onImage = generateTintedImage(image: onImage, color: UIColor.black)!
|
||||||
|
return (offImage, halfImage, onImage, true)
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateGraphics() {
|
||||||
|
if self.isDark {
|
||||||
|
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: UIColor(white: 0.6, alpha: 1.0))
|
||||||
|
self.foregroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: .white)
|
||||||
|
} else {
|
||||||
|
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: UIColor(white: 0.6, alpha: 1.0))
|
||||||
|
self.foregroundNode.image = generateStretchableFilledCircleImage(diameter: 4.0, color: .black)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateLayout(layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
func updateLayout(layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||||
self.validLayout = layout
|
self.validLayout = layout
|
||||||
|
|
||||||
let barHeight: CGFloat = 4.0
|
let barHeight: CGFloat = 4.0
|
||||||
let barWidth: CGFloat
|
var barWidth: CGFloat
|
||||||
|
|
||||||
let statusBarHeight: CGFloat
|
let statusBarHeight: CGFloat
|
||||||
let sideInset: CGFloat
|
var sideInset: CGFloat
|
||||||
if let actual = layout.statusBarHeight {
|
if let actual = layout.statusBarHeight {
|
||||||
statusBarHeight = actual
|
statusBarHeight = actual
|
||||||
} else {
|
} else {
|
||||||
@ -141,14 +189,26 @@ final class VolumeControlStatusBarNode: ASDisplayNode {
|
|||||||
sideInset = 12.0
|
sideInset = 12.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let iconRect = CGRect(x: sideInset + 4.0, y: 14.0, width: 21.0, height: 16.0)
|
||||||
if !layout.intrinsicInsets.bottom.isZero {
|
if !layout.intrinsicInsets.bottom.isZero {
|
||||||
barWidth = 92.0 - sideInset * 2.0
|
if layout.size.width > 375.0 {
|
||||||
|
barWidth = 88.0 - sideInset * 2.0
|
||||||
|
} else {
|
||||||
|
barWidth = 80.0 - sideInset * 2.0
|
||||||
|
}
|
||||||
|
if self.graphics != nil {
|
||||||
|
self.iconNode.isHidden = false
|
||||||
|
barWidth -= iconRect.width - 8.0
|
||||||
|
sideInset += iconRect.width + 8.0
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
self.iconNode.isHidden = true
|
||||||
barWidth = layout.size.width - sideInset * 2.0
|
barWidth = layout.size.width - sideInset * 2.0
|
||||||
}
|
}
|
||||||
|
|
||||||
let boundingRect = CGRect(origin: CGPoint(x: sideInset, y: floor((statusBarHeight - barHeight) / 2.0)), size: CGSize(width: barWidth, height: barHeight))
|
let boundingRect = CGRect(origin: CGPoint(x: sideInset, y: floor((statusBarHeight - barHeight) / 2.0)), size: CGSize(width: barWidth, height: barHeight))
|
||||||
|
|
||||||
|
transition.updateFrame(node: self.iconNode, frame: iconRect)
|
||||||
transition.updateFrame(node: self.backgroundNode, frame: boundingRect)
|
transition.updateFrame(node: self.backgroundNode, frame: boundingRect)
|
||||||
transition.updateFrame(node: self.foregroundNode, frame: CGRect(origin: CGPoint(), size: boundingRect.size))
|
transition.updateFrame(node: self.foregroundNode, frame: CGRect(origin: CGPoint(), size: boundingRect.size))
|
||||||
transition.updateFrame(node: self.foregroundClippingNode, frame: CGRect(origin: boundingRect.origin, size: CGSize(width: self.value * boundingRect.width, height: boundingRect.height)))
|
transition.updateFrame(node: self.foregroundClippingNode, frame: CGRect(origin: boundingRect.origin, size: CGSize(width: self.value * boundingRect.width, height: boundingRect.height)))
|
||||||
@ -162,6 +222,16 @@ final class VolumeControlStatusBarNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
self.value = toValue
|
self.value = toValue
|
||||||
self.updateLayout(layout: layout, transition: .animated(duration: 0.25, curve: .spring))
|
self.updateLayout(layout: layout, transition: .animated(duration: 0.25, curve: .spring))
|
||||||
|
|
||||||
|
if let graphics = self.graphics {
|
||||||
|
if self.value > 0.5 {
|
||||||
|
self.iconNode.image = graphics.2
|
||||||
|
} else if self.value > 0.0 {
|
||||||
|
self.iconNode.image = graphics.1
|
||||||
|
} else {
|
||||||
|
self.iconNode.image = graphics.0
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.value = toValue
|
self.value = toValue
|
||||||
}
|
}
|
||||||
|
@ -519,6 +519,10 @@ public class Window1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func setupVolumeControlStatusBarGraphics(_ graphics: (UIImage, UIImage, UIImage)) {
|
||||||
|
self.volumeControlStatusBarNode.graphics = graphics
|
||||||
|
}
|
||||||
|
|
||||||
public func setForceInCallStatusBar(_ forceInCallStatusBarText: String?, transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut)) {
|
public func setForceInCallStatusBar(_ forceInCallStatusBarText: String?, transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut)) {
|
||||||
if self.forceInCallStatusBarText != forceInCallStatusBarText {
|
if self.forceInCallStatusBarText != forceInCallStatusBarText {
|
||||||
self.forceInCallStatusBarText = forceInCallStatusBarText
|
self.forceInCallStatusBarText = forceInCallStatusBarText
|
||||||
|
Loading…
x
Reference in New Issue
Block a user