Added volume control icon

This commit is contained in:
Ilya Laktyushin 2018-11-30 20:04:03 +04:00
parent bb44454500
commit b3419d2af5
2 changed files with 79 additions and 5 deletions

View File

@ -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
} }

View File

@ -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