Fix pattern rendering

This commit is contained in:
Ilya Laktyushin 2019-12-16 16:57:17 +04:00
parent e5cd999eda
commit a35e8c0aa8
4 changed files with 68 additions and 31 deletions

View File

@ -46,6 +46,13 @@ open class TransformImageNode: ASDisplayNode {
} }
} }
public func reset() {
self.disposable.set(nil)
self.currentArguments = nil
self.currentTransform = nil
self.contents = nil
}
public func setSignal(_ signal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>, attemptSynchronously: Bool = false, dispatchOnDisplayLink: Bool = true) { public func setSignal(_ signal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>, attemptSynchronously: Bool = false, dispatchOnDisplayLink: Bool = true) {
let argumentsPromise = self.argumentsPromise let argumentsPromise = self.argumentsPromise

View File

@ -492,12 +492,14 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
strongSelf.immediateBackgroundNode.backgroundColor = UIColor(rgb: UInt32(bitPattern: value)) strongSelf.immediateBackgroundNode.backgroundColor = UIColor(rgb: UInt32(bitPattern: value))
strongSelf.immediateBackgroundNode.image = nil strongSelf.immediateBackgroundNode.image = nil
strongSelf.signalBackgroundNode.isHidden = true strongSelf.signalBackgroundNode.isHidden = true
strongSelf.signalBackgroundNode.contentAnimations = []
strongSelf.signalBackgroundNode.reset()
strongSelf.patternWallpaper = nil strongSelf.patternWallpaper = nil
} else if let wallpaperImage = wallpaperImage { } else if let wallpaperImage = wallpaperImage {
strongSelf.immediateBackgroundNode.image = wallpaperImage strongSelf.immediateBackgroundNode.image = wallpaperImage
strongSelf.signalBackgroundNode.isHidden = true strongSelf.signalBackgroundNode.isHidden = true
strongSelf.signalBackgroundNode.contentAnimations = []
strongSelf.signalBackgroundNode.reset()
strongSelf.patternWallpaper = nil strongSelf.patternWallpaper = nil
} else if let wallpaperSignal = wallpaperSignal { } else if let wallpaperSignal = wallpaperSignal {
strongSelf.signalBackgroundNode.contentMode = .scaleToFill strongSelf.signalBackgroundNode.contentMode = .scaleToFill
@ -512,9 +514,11 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
if dispatch { if dispatch {
if let _ = strongSelf.patternArgumentsDisposable { if let _ = strongSelf.patternArgumentsDisposable {
} else { } else {
strongSelf.signalBackgroundNode.contentAnimations = .subsequentUpdates
let throttledSignal = strongSelf.patternArgumentsPromise.get() let throttledSignal = strongSelf.patternArgumentsPromise.get()
|> mapToThrottled { next -> Signal<TransformImageArguments, NoError> in |> mapToThrottled { next -> Signal<TransformImageArguments, NoError> in
return .single(next) |> then(.complete() |> delay(0.016667, queue: Queue.concurrentDefaultQueue())) return .single(next) |> then(.complete() |> delay(0.033333, queue: Queue.concurrentDefaultQueue()))
} }
strongSelf.patternArgumentsDisposable = (throttledSignal).start(next: { [weak self] arguments in strongSelf.patternArgumentsDisposable = (throttledSignal).start(next: { [weak self] arguments in
@ -674,7 +678,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
} }
self.colorPanelNode.updateState({ _ in self.colorPanelNode.updateState({ _ in
return WallpaperColorPanelNodeState(selection: colorPanelCollapsed ? .none : .first, firstColor: firstColor, defaultColor: defaultColor, secondColor: secondColor, secondColorAvailable: self.state.section != .accent, preview: false) return WallpaperColorPanelNodeState(selection: colorPanelCollapsed ? .none : .first, firstColor: firstColor, defaultColor: defaultColor, secondColor: secondColor, secondColorAvailable: self.state.section != .accent, rotateAvailable: self.state.section == .background, preview: false)
}, animated: animated) }, animated: animated)
needsLayout = true needsLayout = true

View File

@ -325,6 +325,7 @@ struct WallpaperColorPanelNodeState {
var defaultColor: UIColor? var defaultColor: UIColor?
var secondColor: UIColor? var secondColor: UIColor?
var secondColorAvailable: Bool var secondColorAvailable: Bool
var rotateAvailable: Bool
var preview: Bool var preview: Bool
} }
@ -338,6 +339,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
private let bottomSeparatorNode: ASDisplayNode private let bottomSeparatorNode: ASDisplayNode
private let firstColorFieldNode: ColorInputFieldNode private let firstColorFieldNode: ColorInputFieldNode
private let secondColorFieldNode: ColorInputFieldNode private let secondColorFieldNode: ColorInputFieldNode
private let rotateButton: HighlightableButtonNode
private let swapButton: HighlightableButtonNode private let swapButton: HighlightableButtonNode
private let addButton: HighlightableButtonNode private let addButton: HighlightableButtonNode
private let doneButton: HighlightableButtonNode private let doneButton: HighlightableButtonNode
@ -365,15 +367,17 @@ final class WallpaperColorPanelNode: ASDisplayNode {
self.colorPickerNode = WallpaperColorPickerNode(strings: strings) self.colorPickerNode = WallpaperColorPickerNode(strings: strings)
self.rotateButton = HighlightableButtonNode()
self.rotateButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Settings/ThemeColorRotateIcon"), color: theme.chat.inputPanel.panelControlColor), for: .normal)
self.swapButton = HighlightableButtonNode() self.swapButton = HighlightableButtonNode()
self.swapButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Settings/ThemeColorRotateIcon"), color: theme.chat.inputPanel.panelControlColor), for: .normal) self.swapButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Settings/ThemeColorSwapIcon"), color: theme.chat.inputPanel.panelControlColor), for: .normal)
self.addButton = HighlightableButtonNode() self.addButton = HighlightableButtonNode()
self.addButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Settings/ThemeColorAddIcon"), color: theme.chat.inputPanel.panelControlColor), for: .normal) self.addButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Settings/ThemeColorAddIcon"), color: theme.chat.inputPanel.panelControlColor), for: .normal)
self.firstColorFieldNode = ColorInputFieldNode(theme: theme) self.firstColorFieldNode = ColorInputFieldNode(theme: theme)
self.secondColorFieldNode = ColorInputFieldNode(theme: theme) self.secondColorFieldNode = ColorInputFieldNode(theme: theme)
self.state = WallpaperColorPanelNodeState(selection: .first, firstColor: nil, secondColor: nil, secondColorAvailable: false, preview: false) self.state = WallpaperColorPanelNodeState(selection: .first, firstColor: nil, secondColor: nil, secondColorAvailable: false, rotateAvailable: false, preview: false)
super.init() super.init()
@ -385,9 +389,11 @@ final class WallpaperColorPanelNode: ASDisplayNode {
self.addSubnode(self.doneButton) self.addSubnode(self.doneButton)
self.addSubnode(self.colorPickerNode) self.addSubnode(self.colorPickerNode)
self.addSubnode(self.rotateButton)
self.addSubnode(self.swapButton) self.addSubnode(self.swapButton)
self.addSubnode(self.addButton) self.addSubnode(self.addButton)
self.rotateButton.addTarget(self, action: #selector(self.rotatePressed), forControlEvents: .touchUpInside)
self.swapButton.addTarget(self, action: #selector(self.swapPressed), forControlEvents: .touchUpInside) self.swapButton.addTarget(self, action: #selector(self.swapPressed), forControlEvents: .touchUpInside)
self.addButton.addTarget(self, action: #selector(self.addPressed), forControlEvents: .touchUpInside) self.addButton.addTarget(self, action: #selector(self.addPressed), forControlEvents: .touchUpInside)
@ -591,8 +597,14 @@ final class WallpaperColorPanelNode: ASDisplayNode {
} }
} }
if let buttonSnapshotView = self.swapButton.view.snapshotContentTree() { let middleButton: ASDisplayNode
buttonSnapshotView.frame = self.swapButton.frame if self.rotateButton.alpha > 1.0 {
middleButton = self.rotateButton
} else {
middleButton = self.swapButton
}
if let buttonSnapshotView = middleButton.view.snapshotContentTree() {
buttonSnapshotView.frame = middleButton.frame
self.view.addSubview(buttonSnapshotView) self.view.addSubview(buttonSnapshotView)
buttonSnapshotView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: offset, y: 0.0), duration: 0.3, delay: 0.0, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true, force: false) { _ in buttonSnapshotView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: offset, y: 0.0), duration: 0.3, delay: 0.0, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue, removeOnCompletion: false, additive: true, force: false) { _ in
@ -600,6 +612,7 @@ final class WallpaperColorPanelNode: ASDisplayNode {
} }
} }
self.rotateButton.alpha = 0.0
self.swapButton.alpha = 0.0 self.swapButton.alpha = 0.0
let buttonOffset: CGFloat = (rightInsetWithButton - 13.0) / 2.0 let buttonOffset: CGFloat = (rightInsetWithButton - 13.0) / 2.0
@ -642,24 +655,34 @@ final class WallpaperColorPanelNode: ASDisplayNode {
let buttonSize = CGSize(width: 26.0, height: 26.0) let buttonSize = CGSize(width: 26.0, height: 26.0)
let buttonOffset: CGFloat = (rightInsetWithButton - 13.0) / 2.0 let buttonOffset: CGFloat = (rightInsetWithButton - 13.0) / 2.0
let swapButtonFrame = CGRect(origin: CGPoint(x: self.state.secondColor != nil ? floor((size.width - 26.0) / 2.0) : (self.state.secondColorAvailable ? size.width - rightInsetWithButton + floor((rightInsetWithButton - buttonSize.width) / 2.0) : size.width + buttonOffset), y: floor((topPanelHeight - buttonSize.height) / 2.0)), size: buttonSize) let middleButtonFrame = CGRect(origin: CGPoint(x: self.state.secondColor != nil ? floor((size.width - 26.0) / 2.0) : (self.state.secondColorAvailable ? size.width - rightInsetWithButton + floor((rightInsetWithButton - buttonSize.width) / 2.0) : size.width + buttonOffset), y: floor((topPanelHeight - buttonSize.height) / 2.0)), size: buttonSize)
transition.updateFrame(node: self.swapButton, frame: swapButtonFrame) transition.updateFrame(node: self.rotateButton, frame: middleButtonFrame)
transition.updateFrame(node: self.addButton, frame: swapButtonFrame) transition.updateFrame(node: self.swapButton, frame: middleButtonFrame)
transition.updateFrame(node: self.addButton, frame: middleButtonFrame)
let rotateButtonAlpha: CGFloat
let swapButtonAlpha: CGFloat let swapButtonAlpha: CGFloat
let addButtonAlpha: CGFloat let addButtonAlpha: CGFloat
if let _ = self.state.secondColor { if let _ = self.state.secondColor {
if self.state.rotateAvailable {
rotateButtonAlpha = 1.0
swapButtonAlpha = 0.0
} else {
rotateButtonAlpha = 0.0
swapButtonAlpha = 1.0 swapButtonAlpha = 1.0
}
addButtonAlpha = 0.0 addButtonAlpha = 0.0
} else { } else {
swapButtonAlpha = 0.0 swapButtonAlpha = 0.0
rotateButtonAlpha = 0.0
if self.state.secondColorAvailable { if self.state.secondColorAvailable {
addButtonAlpha = 1.0 addButtonAlpha = 1.0
} else { } else {
addButtonAlpha = 0.0 addButtonAlpha = 0.0
} }
} }
transition.updateAlpha(node: self.rotateButton, alpha: rotateButtonAlpha)
transition.updateAlpha(node: self.swapButton, alpha: swapButtonAlpha) transition.updateAlpha(node: self.swapButton, alpha: swapButtonAlpha)
transition.updateAlpha(node: self.addButton, alpha: addButtonAlpha) transition.updateAlpha(node: self.addButton, alpha: addButtonAlpha)
@ -682,16 +705,19 @@ final class WallpaperColorPanelNode: ASDisplayNode {
self.colorPickerNode.updateLayout(size: colorPickerSize, transition: transition) self.colorPickerNode.updateLayout(size: colorPickerSize, transition: transition)
} }
@objc private func swapPressed() { @objc private func rotatePressed() {
self.rotate?() self.rotate?()
// self.updateState({ current in }
// var updated = current
// if let secondColor = current.secondColor { @objc private func swapPressed() {
// updated.firstColor = secondColor self.updateState({ current in
// updated.secondColor = current.firstColor var updated = current
// } if let secondColor = current.secondColor {
// return updated updated.firstColor = secondColor
// }) updated.secondColor = current.firstColor
}
return updated
})
} }
@objc private func addPressed() { @objc private func addPressed() {

View File

@ -413,6 +413,15 @@ public func patternWallpaperImageInternal(thumbnailData: Data?, fullSizeData: Da
return .single((thumbnailData, fullSizeData, fullSizeComplete)) return .single((thumbnailData, fullSizeData, fullSizeComplete))
|> map { (thumbnailData, fullSizeData, fullSizeComplete) in |> map { (thumbnailData, fullSizeData, fullSizeComplete) in
var fullSizeImage: CGImage?
if let fullSizeData = fullSizeData, fullSizeComplete {
let options = NSMutableDictionary()
options[kCGImageSourceShouldCache as NSString] = false as NSNumber
if let imageSource = CGImageSourceCreateWithData(fullSizeData as CFData, nil), let image = CGImageSourceCreateImageAtIndex(imageSource, 0, options as CFDictionary) {
fullSizeImage = image
}
}
return { arguments in return { arguments in
var scale = scale var scale = scale
@ -427,15 +436,6 @@ public func patternWallpaperImageInternal(thumbnailData: Data?, fullSizeData: Da
let fittedRect = CGRect(origin: CGPoint(x: drawingRect.origin.x + (drawingRect.size.width - fittedSize.width) / 2.0, y: drawingRect.origin.y + (drawingRect.size.height - fittedSize.height) / 2.0), size: fittedSize) let fittedRect = CGRect(origin: CGPoint(x: drawingRect.origin.x + (drawingRect.size.width - fittedSize.width) / 2.0, y: drawingRect.origin.y + (drawingRect.size.height - fittedSize.height) / 2.0), size: fittedSize)
var fullSizeImage: CGImage?
if let fullSizeData = fullSizeData, fullSizeComplete {
let options = NSMutableDictionary()
options[kCGImageSourceShouldCache as NSString] = false as NSNumber
if let imageSource = CGImageSourceCreateWithData(fullSizeData as CFData, nil), let image = CGImageSourceCreateImageAtIndex(imageSource, 0, options as CFDictionary) {
fullSizeImage = image
}
}
if let customArguments = arguments.custom as? PatternWallpaperArguments, let combinedColor = customArguments.colors.first { if let customArguments = arguments.custom as? PatternWallpaperArguments, let combinedColor = customArguments.colors.first {
if customArguments.preview { if customArguments.preview {
scale = max(1.0, UIScreenScale - 1.0) scale = max(1.0, UIScreenScale - 1.0)