From a35e8c0aa8aa686cf0a37f172dfc9d738bb3b472 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Mon, 16 Dec 2019 16:57:17 +0400 Subject: [PATCH] Fix pattern rendering --- .../Display/Display/TransformImageNode.swift | 7 +++ .../ThemeAccentColorControllerNode.swift | 12 ++-- .../Themes/WallpaperColorPanelNode.swift | 60 +++++++++++++------ .../Sources/WallpaperResources.swift | 20 +++---- 4 files changed, 68 insertions(+), 31 deletions(-) diff --git a/submodules/Display/Display/TransformImageNode.swift b/submodules/Display/Display/TransformImageNode.swift index 36e72a6568..163b0ce437 100644 --- a/submodules/Display/Display/TransformImageNode.swift +++ b/submodules/Display/Display/TransformImageNode.swift @@ -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) { let argumentsPromise = self.argumentsPromise diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift index 4e71b8e8bf..dd8a0cfa6b 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift @@ -492,12 +492,14 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate strongSelf.immediateBackgroundNode.backgroundColor = UIColor(rgb: UInt32(bitPattern: value)) strongSelf.immediateBackgroundNode.image = nil strongSelf.signalBackgroundNode.isHidden = true - + strongSelf.signalBackgroundNode.contentAnimations = [] + strongSelf.signalBackgroundNode.reset() strongSelf.patternWallpaper = nil } else if let wallpaperImage = wallpaperImage { strongSelf.immediateBackgroundNode.image = wallpaperImage strongSelf.signalBackgroundNode.isHidden = true - + strongSelf.signalBackgroundNode.contentAnimations = [] + strongSelf.signalBackgroundNode.reset() strongSelf.patternWallpaper = nil } else if let wallpaperSignal = wallpaperSignal { strongSelf.signalBackgroundNode.contentMode = .scaleToFill @@ -512,9 +514,11 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate if dispatch { if let _ = strongSelf.patternArgumentsDisposable { } else { + strongSelf.signalBackgroundNode.contentAnimations = .subsequentUpdates + let throttledSignal = strongSelf.patternArgumentsPromise.get() |> mapToThrottled { next -> Signal 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 @@ -674,7 +678,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate } 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) needsLayout = true diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperColorPanelNode.swift b/submodules/SettingsUI/Sources/Themes/WallpaperColorPanelNode.swift index 6cba98b03f..c15e0266de 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperColorPanelNode.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperColorPanelNode.swift @@ -325,6 +325,7 @@ struct WallpaperColorPanelNodeState { var defaultColor: UIColor? var secondColor: UIColor? var secondColorAvailable: Bool + var rotateAvailable: Bool var preview: Bool } @@ -338,6 +339,7 @@ final class WallpaperColorPanelNode: ASDisplayNode { private let bottomSeparatorNode: ASDisplayNode private let firstColorFieldNode: ColorInputFieldNode private let secondColorFieldNode: ColorInputFieldNode + private let rotateButton: HighlightableButtonNode private let swapButton: HighlightableButtonNode private let addButton: HighlightableButtonNode private let doneButton: HighlightableButtonNode @@ -365,15 +367,17 @@ final class WallpaperColorPanelNode: ASDisplayNode { 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.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.setImage(generateTintedImage(image: UIImage(bundleImageName: "Settings/ThemeColorAddIcon"), color: theme.chat.inputPanel.panelControlColor), for: .normal) self.firstColorFieldNode = 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() @@ -385,9 +389,11 @@ final class WallpaperColorPanelNode: ASDisplayNode { self.addSubnode(self.doneButton) self.addSubnode(self.colorPickerNode) + self.addSubnode(self.rotateButton) self.addSubnode(self.swapButton) 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.addButton.addTarget(self, action: #selector(self.addPressed), forControlEvents: .touchUpInside) @@ -591,8 +597,14 @@ final class WallpaperColorPanelNode: ASDisplayNode { } } - if let buttonSnapshotView = self.swapButton.view.snapshotContentTree() { - buttonSnapshotView.frame = self.swapButton.frame + let middleButton: ASDisplayNode + 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) 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 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 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.addButton, frame: swapButtonFrame) + transition.updateFrame(node: self.rotateButton, frame: middleButtonFrame) + transition.updateFrame(node: self.swapButton, frame: middleButtonFrame) + transition.updateFrame(node: self.addButton, frame: middleButtonFrame) + let rotateButtonAlpha: CGFloat let swapButtonAlpha: CGFloat let addButtonAlpha: CGFloat if let _ = self.state.secondColor { - swapButtonAlpha = 1.0 + if self.state.rotateAvailable { + rotateButtonAlpha = 1.0 + swapButtonAlpha = 0.0 + } else { + rotateButtonAlpha = 0.0 + swapButtonAlpha = 1.0 + } addButtonAlpha = 0.0 } else { swapButtonAlpha = 0.0 + rotateButtonAlpha = 0.0 if self.state.secondColorAvailable { addButtonAlpha = 1.0 } else { addButtonAlpha = 0.0 } } + transition.updateAlpha(node: self.rotateButton, alpha: rotateButtonAlpha) transition.updateAlpha(node: self.swapButton, alpha: swapButtonAlpha) transition.updateAlpha(node: self.addButton, alpha: addButtonAlpha) @@ -682,16 +705,19 @@ final class WallpaperColorPanelNode: ASDisplayNode { self.colorPickerNode.updateLayout(size: colorPickerSize, transition: transition) } - @objc private func swapPressed() { + @objc private func rotatePressed() { self.rotate?() -// self.updateState({ current in -// var updated = current -// if let secondColor = current.secondColor { -// updated.firstColor = secondColor -// updated.secondColor = current.firstColor -// } -// return updated -// }) + } + + @objc private func swapPressed() { + self.updateState({ current in + var updated = current + if let secondColor = current.secondColor { + updated.firstColor = secondColor + updated.secondColor = current.firstColor + } + return updated + }) } @objc private func addPressed() { diff --git a/submodules/WallpaperResources/Sources/WallpaperResources.swift b/submodules/WallpaperResources/Sources/WallpaperResources.swift index 195f353fc5..a9ff275f7d 100644 --- a/submodules/WallpaperResources/Sources/WallpaperResources.swift +++ b/submodules/WallpaperResources/Sources/WallpaperResources.swift @@ -413,6 +413,15 @@ public func patternWallpaperImageInternal(thumbnailData: Data?, fullSizeData: Da return .single((thumbnailData, fullSizeData, fullSizeComplete)) |> 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 var scale = scale @@ -426,16 +435,7 @@ 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) - - 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 customArguments.preview { scale = max(1.0, UIScreenScale - 1.0)