From 2adf8a010dcf65c129ba4f9294e8aae72a497db7 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Fri, 3 Mar 2023 12:11:34 +0400 Subject: [PATCH] Tune wallpaper pattern scale on iPad --- .../Sources/MediaPickerSelectedListNode.swift | 2 +- .../BubbleSettingsController.swift | 2 +- .../ForwardPrivacyChatPreviewItem.swift | 49 +++++++++---------- .../Reactions/ReactionChatPreviewItem.swift | 17 ++++++- .../TextSizeSelectionController.swift | 2 +- .../ThemeAccentColorControllerNode.swift | 2 +- .../Themes/ThemePreviewControllerNode.swift | 4 +- .../Themes/ThemeSettingsChatPreviewItem.swift | 18 ++++++- .../Sources/Themes/WallpaperGalleryItem.swift | 10 +++- .../Sources/ShareController.swift | 2 +- .../Sources/ChatControllerNode.swift | 6 +-- .../TelegramUI/Sources/ChatQrCodeScreen.swift | 11 ++++- .../ChatRecentActionsControllerNode.swift | 2 +- .../MetalWallpaperBackgroundNode.swift | 2 +- .../Sources/WallpaperBackgroundNode.swift | 41 +++++++++++----- .../Sources/WallpaperResources.swift | 39 +++++++++------ 16 files changed, 139 insertions(+), 70 deletions(-) diff --git a/submodules/MediaPickerUI/Sources/MediaPickerSelectedListNode.swift b/submodules/MediaPickerUI/Sources/MediaPickerSelectedListNode.swift index 3daf7cbe3b..ff17f148e5 100644 --- a/submodules/MediaPickerUI/Sources/MediaPickerSelectedListNode.swift +++ b/submodules/MediaPickerUI/Sources/MediaPickerSelectedListNode.swift @@ -1070,7 +1070,7 @@ final class MediaPickerSelectedListNode: ASDisplayNode, UIScrollViewDelegate, UI self.wallpaperBackgroundNode.update(wallpaper: wallpaper) self.wallpaperBackgroundNode.updateBubbleTheme(bubbleTheme: theme, bubbleCorners: bubbleCorners) transition.updateFrame(node: self.wallpaperBackgroundNode, frame: CGRect(origin: CGPoint(x: inset, y: 0.0), size: CGSize(width: size.width - inset * 2.0, height: size.height))) - self.wallpaperBackgroundNode.updateLayout(size: CGSize(width: size.width - inset * 2.0, height: size.height), tile: false, transition: transition) + self.wallpaperBackgroundNode.updateLayout(size: CGSize(width: size.width - inset * 2.0, height: size.height), displayMode: .aspectFill, transition: transition) self.updateItems(transition: itemsTransition) diff --git a/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift b/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift index 569f73d169..c2185c0ffb 100644 --- a/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift +++ b/submodules/SettingsUI/Sources/BubbleSettings/BubbleSettingsController.swift @@ -285,7 +285,7 @@ private final class BubbleSettingsControllerNode: ASDisplayNode, UIScrollViewDel bottomInset = 37.0 self.chatBackgroundNode.frame = chatFrame - self.chatBackgroundNode.updateLayout(size: chatFrame.size, tile: false, transition: transition) + self.chatBackgroundNode.updateLayout(size: chatFrame.size, displayMode: .aspectFill, transition: transition) self.messagesContainerNode.frame = chatFrame transition.updateFrame(node: self.toolbarNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - toolbarHeight), size: CGSize(width: layout.size.width, height: toolbarHeight + layout.intrinsicInsets.bottom))) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift b/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift index 97099c175b..ee82b17a04 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/ForwardPrivacyChatPreviewItem.swift @@ -179,29 +179,11 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode { let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets) let layoutSize = layout.size - var authorNameCenter: CGFloat? + let attributedMeasureText = NSAttributedString(string: item.peerName, font: Font.regular(13.0), textColor: .black) + let (authorNameLayout, _) = makeTextLayout(TextNodeLayoutArguments(attributedString: attributedMeasureText, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, lineSpacing: 0.0, cutout: nil, insets: UIEdgeInsets())) - let forwardedString = item.strings.Message_ForwardedMessageShort("").string - var fromString: String? - if let newlineRange = forwardedString.range(of: "\n") { - let from = forwardedString[newlineRange.upperBound...] - if !from.isEmpty { - fromString = String(from) - } - } - let authorString = item.peerName - - if let fromString = fromString { - var attributedMeasureText = NSAttributedString(string: fromString, font: Font.regular(13.0), textColor: .black) - let (fromTextLayout, _) = makeTextLayout(TextNodeLayoutArguments(attributedString: attributedMeasureText, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, lineSpacing: 0.0, cutout: nil, insets: UIEdgeInsets())) - - let fromWidth = fromTextLayout.size.width - attributedMeasureText = NSAttributedString(string: authorString, font: Font.regular(13.0), textColor: .black) - let (authorNameLayout, _) = makeTextLayout(TextNodeLayoutArguments(attributedString: attributedMeasureText, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, lineSpacing: 0.0, cutout: nil, insets: UIEdgeInsets())) - - let authorNameWidth = authorNameLayout.size.width - authorNameCenter = fromWidth + authorNameWidth / 2.0 + 3.0 - } + let authorNameWidth = authorNameLayout.size.width + let authorNameCenter = authorNameWidth / 2.0 + 3.0 return (layout, { [weak self] in if let strongSelf = self { @@ -264,11 +246,26 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode { let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight))) + let displayMode: WallpaperDisplayMode + if abs(params.availableHeight - params.width) < 100.0, params.availableHeight > 700.0 { + displayMode = .halfAspectFill + } else { + if backgroundFrame.width > backgroundFrame.height * 4.0 { + if params.availableHeight < 700.0 { + displayMode = .halfAspectFill + } else { + displayMode = .aspectFill + } + } else { + displayMode = .aspectFill + } + } + if let backgroundNode = strongSelf.backgroundNode { backgroundNode.frame = backgroundFrame.insetBy(dx: 0.0, dy: -100.0) backgroundNode.update(wallpaper: item.wallpaper) backgroundNode.updateBubbleTheme(bubbleTheme: item.theme, bubbleCorners: item.chatBubbleCorners) - backgroundNode.updateLayout(size: backgroundNode.bounds.size, tile: false, transition: .immediate) + backgroundNode.updateLayout(size: backgroundNode.bounds.size, displayMode: displayMode, transition: .immediate) } strongSelf.maskNode.frame = backgroundFrame.insetBy(dx: params.leftInset, dy: 0.0) @@ -285,10 +282,8 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode { var sourceRect: CGRect if let messageNode = strongSelf.messageNode as? ChatMessagePreviewItemNode, let forwardInfoNode = messageNode.forwardInfoReferenceNode { sourceRect = forwardInfoNode.convert(forwardInfoNode.bounds, to: strongSelf) - if let authorNameCenter = authorNameCenter { - sourceRect.origin = CGPoint(x: sourceRect.minX + authorNameCenter, y: sourceRect.minY) - sourceRect.size.width = 0.0 - } + sourceRect.origin = CGPoint(x: sourceRect.minX + authorNameCenter, y: sourceRect.minY) + sourceRect.size.width = 0.0 } else { sourceRect = CGRect(origin: CGPoint(x: layout.size.width / 2.0, y: layout.size.height / 2.0), size: CGSize()) } diff --git a/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift b/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift index ea4301421f..74293fd2ba 100644 --- a/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift +++ b/submodules/SettingsUI/Sources/Reactions/ReactionChatPreviewItem.swift @@ -389,11 +389,26 @@ class ReactionChatPreviewItemNode: ListViewItemNode { let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight))) + let displayMode: WallpaperDisplayMode + if abs(params.availableHeight - params.width) < 100.0, params.availableHeight > 700.0 { + displayMode = .halfAspectFill + } else { + if backgroundFrame.width > backgroundFrame.height * 4.0 { + if params.availableHeight < 700.0 { + displayMode = .halfAspectFill + } else { + displayMode = .aspectFill + } + } else { + displayMode = .aspectFill + } + } + if let backgroundNode = strongSelf.backgroundNode { backgroundNode.frame = backgroundFrame.insetBy(dx: 0.0, dy: -100.0) backgroundNode.update(wallpaper: item.wallpaper) backgroundNode.updateBubbleTheme(bubbleTheme: item.theme, bubbleCorners: item.chatBubbleCorners) - backgroundNode.updateLayout(size: backgroundNode.bounds.size, tile: false, transition: .immediate) + backgroundNode.updateLayout(size: backgroundNode.bounds.size, displayMode: displayMode, transition: .immediate) } strongSelf.maskNode.frame = backgroundFrame.insetBy(dx: params.leftInset, dy: 0.0) diff --git a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift index 357bc28fdb..046b9e9e6d 100644 --- a/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift +++ b/submodules/SettingsUI/Sources/Text Size/TextSizeSelectionController.swift @@ -564,7 +564,7 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView } self.chatBackgroundNode.frame = chatFrame - self.chatBackgroundNode.updateLayout(size: chatFrame.size, tile: false, transition: transition) + self.chatBackgroundNode.updateLayout(size: chatFrame.size, displayMode: .aspectFill, transition: transition) self.messagesContainerNode.frame = chatFrame transition.updateFrame(node: self.toolbarNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - toolbarHeight), size: CGSize(width: layout.size.width, height: toolbarHeight + layout.intrinsicInsets.bottom))) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift index 29704b9d12..972fb056ba 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift @@ -1198,7 +1198,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate transition.updateFrame(node: self.backgroundContainerNode, frame: CGRect(origin: CGPoint(), size: backgroundSize)) transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: layout.size)) - self.backgroundNode.updateLayout(size: self.backgroundNode.bounds.size, tile: false, transition: transition) + self.backgroundNode.updateLayout(size: self.backgroundNode.bounds.size, displayMode: .aspectFill, transition: transition) transition.updatePosition(node: self.backgroundWrapperNode, position: CGPoint(x: backgroundSize.width / 2.0, y: backgroundSize.height / 2.0)) diff --git a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift index 487eac0b8a..35b0762523 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift @@ -712,11 +712,11 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { self.messagesContainerNode.frame = self.chatContainerNode.bounds self.instantChatBackgroundNode.frame = self.chatContainerNode.bounds - self.instantChatBackgroundNode.updateLayout(size: self.instantChatBackgroundNode.bounds.size, tile: false, transition: .immediate) + self.instantChatBackgroundNode.updateLayout(size: self.instantChatBackgroundNode.bounds.size, displayMode: .aspectFill, transition: .immediate) self.remoteChatBackgroundNode.frame = self.chatContainerNode.bounds self.blurredNode.frame = self.chatContainerNode.bounds self.wallpaperNode.frame = self.chatContainerNode.bounds - self.wallpaperNode.updateLayout(size: self.wallpaperNode.bounds.size, tile: false, transition: .immediate) + self.wallpaperNode.updateLayout(size: self.wallpaperNode.bounds.size, displayMode: .aspectFill, transition: .immediate) transition.updateFrame(node: self.toolbarNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - toolbarHeight), size: CGSize(width: layout.size.width, height: toolbarHeight))) self.toolbarNode.updateLayout(size: CGSize(width: layout.size.width, height: 49.0), layout: layout, transition: transition) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift index 5aa5b1274d..b937620142 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift @@ -265,9 +265,25 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.componentTheme, top: hasTopCorners, bottom: hasBottomCorners) : nil let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight))) + + let displayMode: WallpaperDisplayMode + if abs(params.availableHeight - params.width) < 100.0, params.availableHeight > 700.0 { + displayMode = .halfAspectFill + } else { + if backgroundFrame.width > backgroundFrame.height * 4.0 { + if params.availableHeight < 700.0 { + displayMode = .halfAspectFill + } else { + displayMode = .aspectFill + } + } else { + displayMode = .aspectFill + } + } + if let backgroundNode = strongSelf.backgroundNode { backgroundNode.frame = backgroundFrame.insetBy(dx: 0.0, dy: -100.0) - backgroundNode.updateLayout(size: backgroundNode.bounds.size, tile: false, transition: .immediate) + backgroundNode.updateLayout(size: backgroundNode.bounds.size, displayMode: displayMode, transition: .immediate) } strongSelf.maskNode.frame = backgroundFrame.insetBy(dx: params.leftInset, dy: 0.0) strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight)) diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift index 886b241fe1..09d2b515d8 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift @@ -1169,7 +1169,15 @@ final class WallpaperGalleryItemNode: GalleryItemNode { if self.cropNode.supernode == nil { self.imageNode.frame = self.wrapperNode.bounds self.nativeNode.frame = self.wrapperNode.bounds - self.nativeNode.updateLayout(size: self.nativeNode.bounds.size, tile: false, transition: .immediate) + + let displayMode: WallpaperDisplayMode + if case .regular = layout.metrics.widthClass { + displayMode = .aspectFit + } else { + displayMode = .aspectFill + } + + self.nativeNode.updateLayout(size: self.nativeNode.bounds.size, displayMode: displayMode, transition: .immediate) self.blurredNode.frame = self.imageNode.frame } else { self.cropNode.frame = self.wrapperNode.bounds diff --git a/submodules/ShareController/Sources/ShareController.swift b/submodules/ShareController/Sources/ShareController.swift index 1f3d7b8050..d40af9242a 100644 --- a/submodules/ShareController/Sources/ShareController.swift +++ b/submodules/ShareController/Sources/ShareController.swift @@ -1625,7 +1625,7 @@ final class MessageStoryRenderer { let size = layout.size self.containerNode.frame = CGRect(origin: CGPoint(), size: layout.size) self.instantChatBackgroundNode.frame = CGRect(origin: CGPoint(), size: layout.size) - self.instantChatBackgroundNode.updateLayout(size: size, tile: false, transition: .immediate) + self.instantChatBackgroundNode.updateLayout(size: size, displayMode: .aspectFill, transition: .immediate) self.messagesContainerNode.frame = CGRect(origin: CGPoint(), size: layout.size) let addressLayout = self.addressNode.updateLayout(size) diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index b783cbd8a7..cdf2e1414c 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -1469,11 +1469,11 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { transition.updateFrame(node: self.backgroundNode, frame: contentBounds) - var shouldTile = false + var displayMode: WallpaperDisplayMode = .aspectFill if case .regular = layout.metrics.widthClass, layout.size.height == layout.deviceMetrics.screenSize.width { - shouldTile = true + displayMode = .aspectFit } - self.backgroundNode.updateLayout(size: contentBounds.size, tile: shouldTile, transition: transition) + self.backgroundNode.updateLayout(size: contentBounds.size, displayMode: displayMode, transition: transition) transition.updateBounds(node: self.historyNodeContainer, bounds: contentBounds) transition.updatePosition(node: self.historyNodeContainer, position: contentBounds.center) diff --git a/submodules/TelegramUI/Sources/ChatQrCodeScreen.swift b/submodules/TelegramUI/Sources/ChatQrCodeScreen.swift index 2a29f17f0b..e6f5a2760b 100644 --- a/submodules/TelegramUI/Sources/ChatQrCodeScreen.swift +++ b/submodules/TelegramUI/Sources/ChatQrCodeScreen.swift @@ -1852,7 +1852,14 @@ private class QrContentNode: ASDisplayNode, ContentNode { transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(), size: size)) transition.updateFrame(node: self.wallpaperBackgroundNode, frame: CGRect(origin: CGPoint(), size: size)) - self.wallpaperBackgroundNode.updateLayout(size: size, tile: false, transition: transition) + + let displayMode: WallpaperDisplayMode + if max(size.width, size.height) > 1000.0 { + displayMode = .aspectFit + } else { + displayMode = .aspectFill + } + self.wallpaperBackgroundNode.updateLayout(size: size, displayMode: displayMode, transition: transition) let textLength = self.codeTextNode.attributedText?.string.count ?? 0 @@ -2195,7 +2202,7 @@ private class MessageContentNode: ASDisplayNode, ContentNode { transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(), size: size)) transition.updateFrame(node: self.wallpaperBackgroundNode, frame: CGRect(origin: CGPoint(), size: size)) - self.wallpaperBackgroundNode.updateLayout(size: size, tile: false, transition: transition) + self.wallpaperBackgroundNode.updateLayout(size: size, displayMode: .aspectFill, transition: transition) let inset: CGFloat = 24.0 let contentInset: CGFloat = 16.0 diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift index 9f0ba3b33d..1bdf8d5238 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift @@ -666,7 +666,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { let cleanInsets = layout.insets(options: []) transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: layout.size)) - self.backgroundNode.updateLayout(size: self.backgroundNode.bounds.size, tile: false, transition: transition) + self.backgroundNode.updateLayout(size: self.backgroundNode.bounds.size, displayMode: .aspectFill, transition: transition) let intrinsicPanelHeight: CGFloat = 47.0 let panelHeight = intrinsicPanelHeight + cleanInsets.bottom diff --git a/submodules/WallpaperBackgroundNode/Sources/MetalWallpaperBackgroundNode.swift b/submodules/WallpaperBackgroundNode/Sources/MetalWallpaperBackgroundNode.swift index 20394de160..ae77acc904 100644 --- a/submodules/WallpaperBackgroundNode/Sources/MetalWallpaperBackgroundNode.swift +++ b/submodules/WallpaperBackgroundNode/Sources/MetalWallpaperBackgroundNode.swift @@ -138,7 +138,7 @@ final class MetalWallpaperBackgroundNode: ASDisplayNode, WallpaperBackgroundNode } - func updateLayout(size: CGSize, tile: Bool, transition: ContainedViewLayoutTransition) { + func updateLayout(size: CGSize, displayMode: WallpaperDisplayMode, transition: ContainedViewLayoutTransition) { if self.metalLayer.drawableSize != size { self.metalLayer.drawableSize = size diff --git a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift index b580c8d23e..0b1d24c63d 100644 --- a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift +++ b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift @@ -54,13 +54,30 @@ public protocol WallpaperBubbleBackgroundNode: ASDisplayNode { func offsetSpring(value: CGFloat, duration: Double, damping: CGFloat) } +public enum WallpaperDisplayMode { + case aspectFill + case aspectFit + case halfAspectFill + + var argumentsDisplayMode: PatternWallpaperArguments.DisplayMode { + switch self { + case .aspectFill: + return .aspectFill + case .aspectFit: + return .aspectFit + case .halfAspectFill: + return .halfAspectFill + } + } +} + public protocol WallpaperBackgroundNode: ASDisplayNode { var isReady: Signal { get } var rotation: CGFloat { get set } func update(wallpaper: TelegramWallpaper) func _internalUpdateIsSettingUpWallpaper() - func updateLayout(size: CGSize, tile: Bool, transition: ContainedViewLayoutTransition) + func updateLayout(size: CGSize, displayMode: WallpaperDisplayMode, transition: ContainedViewLayoutTransition) func updateIsLooping(_ isLooping: Bool) func animateEvent(transition: ContainedViewLayoutTransition, extendAnimation: Bool) func updateBubbleTheme(bubbleTheme: PresentationTheme, bubbleCorners: PresentationChatBubbleCorners) @@ -599,7 +616,7 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode private let bakedBackgroundView: UIImageView - private var validLayout: (CGSize, Bool)? + private var validLayout: (CGSize, WallpaperDisplayMode)? private var wallpaper: TelegramWallpaper? private var isSettingUpWallpaper: Bool = false @@ -884,8 +901,8 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode } } - if let (size, tile) = self.validLayout { - self.updateLayout(size: size, tile: tile, transition: .immediate) + if let (size, displayMode) = self.validLayout { + self.updateLayout(size: size, displayMode: displayMode, transition: .immediate) self.updateBubbles() if scheduleLoopingEvent { @@ -953,7 +970,7 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode } } - private func loadPatternForSizeIfNeeded(size: CGSize, tile: Bool, transition: ContainedViewLayoutTransition) { + private func loadPatternForSizeIfNeeded(size: CGSize, displayMode: WallpaperDisplayMode, transition: ContainedViewLayoutTransition) { guard let wallpaper = self.wallpaper else { return } @@ -1024,8 +1041,8 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode strongSelf.validPatternImage = ValidPatternImage(wallpaper: wallpaper, invertPattern: invertPattern, generate: generator) strongSelf.validPatternGeneratedImage = nil - if let (size, tile) = strongSelf.validLayout { - strongSelf.loadPatternForSizeIfNeeded(size: size, tile: tile, transition: .immediate) + if let (size, displayMode) = strongSelf.validLayout { + strongSelf.loadPatternForSizeIfNeeded(size: size, displayMode: displayMode, transition: .immediate) } else { strongSelf._isReady.set(true) } @@ -1067,7 +1084,7 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode self.patternImageLayer.suspendCompositionUpdates = false self.patternImageLayer.updateCompositionIfNeeded() } else { - let patternArguments = TransformImageArguments(corners: ImageCorners(), imageSize: size, boundingSize: size, intrinsicInsets: UIEdgeInsets(), custom: PatternWallpaperArguments(colors: [patternBackgroundColor], rotation: nil, customPatternColor: patternColor, preview: false, tile: tile), scale: min(2.0, UIScreenScale)) + let patternArguments = TransformImageArguments(corners: ImageCorners(), imageSize: size, boundingSize: size, intrinsicInsets: UIEdgeInsets(), custom: PatternWallpaperArguments(colors: [patternBackgroundColor], rotation: nil, customPatternColor: patternColor, preview: false, displayMode: displayMode.argumentsDisplayMode), scale: min(2.0, UIScreenScale)) if self.useSharedAnimationPhase || self.patternImageLayer.contents == nil { if let drawingContext = validPatternImage.generate(patternArguments) { if let image = drawingContext.generateImage() { @@ -1121,9 +1138,9 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode transition.updateFrame(layer: self.patternImageLayer, frame: CGRect(origin: CGPoint(), size: size)) } - func updateLayout(size: CGSize, tile: Bool, transition: ContainedViewLayoutTransition) { + func updateLayout(size: CGSize, displayMode: WallpaperDisplayMode, transition: ContainedViewLayoutTransition) { let isFirstLayout = self.validLayout == nil - self.validLayout = (size, tile) + self.validLayout = (size, displayMode) if let blurredBackgroundPortalSourceView = self.blurredBackgroundPortalSourceView { transition.updateFrame(view: blurredBackgroundPortalSourceView, frame: CGRect(origin: CGPoint(), size: size)) @@ -1151,7 +1168,7 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode outgoingBubbleGradientBackgroundNode.updateLayout(size: size, transition: transition, extendAnimation: false, backwards: false, completion: {}) } - self.loadPatternForSizeIfNeeded(size: size, tile: tile, transition: transition) + self.loadPatternForSizeIfNeeded(size: size, displayMode: displayMode, transition: transition) /*for (animationNode, relativePosition) in self.inlineAnimationNodes { let sizeNorm = CGSize(width: 1440, height: 2960) @@ -2021,7 +2038,7 @@ final class WallpaperBackgroundNodeMergedImpl: ASDisplayNode, WallpaperBackgroun self.isSettingUpWallpaper = true } - func updateLayout(size: CGSize, tile: Bool, transition: ContainedViewLayoutTransition) { + func updateLayout(size: CGSize, displayMode: WallpaperDisplayMode, transition: ContainedViewLayoutTransition) { self.validLayout = size self.staticView.frame = CGRect(origin: CGPoint(), size: size) diff --git a/submodules/WallpaperResources/Sources/WallpaperResources.swift b/submodules/WallpaperResources/Sources/WallpaperResources.swift index 4f103d3aab..1cdcedf489 100644 --- a/submodules/WallpaperResources/Sources/WallpaperResources.swift +++ b/submodules/WallpaperResources/Sources/WallpaperResources.swift @@ -336,20 +336,25 @@ public enum PatternWallpaperDrawMode { } public struct PatternWallpaperArguments: TransformImageCustomArguments { + public enum DisplayMode: Int32 { + case aspectFill + case aspectFit + case halfAspectFill + } let colors: [UIColor] let rotation: Int32? let preview: Bool let customPatternColor: UIColor? let bakePatternAlpha: CGFloat - let tile: Bool + let displayMode: DisplayMode - public init(colors: [UIColor], rotation: Int32?, customPatternColor: UIColor? = nil, preview: Bool = false, bakePatternAlpha: CGFloat = 1.0, tile: Bool = false) { + public init(colors: [UIColor], rotation: Int32?, customPatternColor: UIColor? = nil, preview: Bool = false, bakePatternAlpha: CGFloat = 1.0, displayMode: DisplayMode = .aspectFill) { self.colors = colors self.rotation = rotation self.customPatternColor = customPatternColor self.preview = preview self.bakePatternAlpha = bakePatternAlpha - self.tile = tile + self.displayMode = displayMode } public func serialized() -> NSArray { @@ -361,7 +366,7 @@ public struct PatternWallpaperArguments: TransformImageCustomArguments { } array.add(NSNumber(value: self.preview)) array.add(NSNumber(value: Double(self.bakePatternAlpha))) - array.add(NSNumber(value: self.tile)) + array.add(NSNumber(value: self.displayMode.rawValue)) return array } } @@ -542,13 +547,13 @@ private func patternWallpaperImageInternal(fullSizeData: Data?, fullSizeComplete c.restoreGState() } - let tile = customArguments.tile + let displayMode = customArguments.displayMode let overlayImage = generateImage(arguments.drawingRect.size, rotatedContext: { size, c in c.clear(CGRect(origin: CGPoint(), size: size)) var image: UIImage? if let fullSizeData = fullSizeData { if mode == .screen { - image = renderPreparedImage(fullSizeData, CGSize(width: size.width * context.scale, height: size.height * context.scale), .black, 1.0, tile) + image = renderPreparedImage(fullSizeData, CGSize(width: size.width * context.scale, height: size.height * context.scale), .black, 1.0, displayMode != .aspectFill) } else { image = UIImage(data: fullSizeData) } @@ -570,10 +575,14 @@ private func patternWallpaperImageInternal(fullSizeData: Data?, fullSizeComplete if abs(fittedSize.height - arguments.boundingSize.height).isLessThanOrEqualTo(CGFloat(1.0)) { fittedSize.height = arguments.boundingSize.height } - if tile { - fittedSize = fittedSize.aspectFitted(arguments.drawingRect.size) - } else { + switch displayMode { + case .aspectFill: fittedSize = fittedSize.aspectFilled(arguments.drawingRect.size) + case .halfAspectFill: + fittedSize = fittedSize.aspectFilled(arguments.drawingRect.size) + fittedSize = CGSize(width: fittedSize.width * 0.5, height: fittedSize.height * 0.5) + case .aspectFit: + fittedSize = fittedSize.aspectFitted(arguments.drawingRect.size) } c.interpolationQuality = customArguments.preview ? .low : .medium @@ -611,16 +620,18 @@ private func patternWallpaperImageInternal(fullSizeData: Data?, fullSizeComplete c.restoreGState() } - if tile { + switch displayMode { + case .aspectFit, .halfAspectFill: var fittedRect = CGRect(origin: CGPoint(x: drawingRect.origin.x, y: drawingRect.origin.y + (drawingRect.size.height - fittedSize.height) / 2.0), size: fittedSize) drawTile(fittedRect) - fittedRect = fittedRect.offsetBy(dx: fittedSize.width, dy: 0.0) - drawTile(fittedRect) - } else { + while (fittedRect.maxX < size.width) { + fittedRect = fittedRect.offsetBy(dx: fittedSize.width, dy: 0.0) + drawTile(fittedRect) + } + case .aspectFill: 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) drawTile(fittedRect) } - } }) if let customPatternColor = customArguments.customPatternColor, customPatternColor.alpha < 1.0 {