diff --git a/submodules/DrawingUI/BUILD b/submodules/DrawingUI/BUILD index 35c361084d..74789fe4ec 100644 --- a/submodules/DrawingUI/BUILD +++ b/submodules/DrawingUI/BUILD @@ -97,6 +97,7 @@ swift_library( "//submodules/ChatPresentationInterfaceState:ChatPresentationInterfaceState", "//submodules/StickerPackPreviewUI:StickerPackPreviewUI", "//submodules/TelegramUI/Components/LottieComponent", + "//submodules/ImageTransparency", ], visibility = [ "//visibility:public", diff --git a/submodules/DrawingUI/Sources/DrawingScreen.swift b/submodules/DrawingUI/Sources/DrawingScreen.swift index bebb78e69b..9e8944c062 100644 --- a/submodules/DrawingUI/Sources/DrawingScreen.swift +++ b/submodules/DrawingUI/Sources/DrawingScreen.swift @@ -3127,6 +3127,12 @@ public final class DrawingToolsInteraction { if let entityView = self.entitiesView.getView(for: entity.uuid) { if let textEntityView = entityView as? DrawingTextEntityView { textEntityView.beginEditing(accessoryView: self.textEditAccessoryView) + + textEntityView.replaceWithImage = { [weak self] image, isSticker in + if let self { + self.insertEntity(DrawingStickerEntity(content: .image(image, isSticker ? .sticker : .rectangle)), scale: 2.5) + } + } } else { if self.isVideo { entityView.seek(to: 0.0) diff --git a/submodules/DrawingUI/Sources/DrawingTextEntity.swift b/submodules/DrawingUI/Sources/DrawingTextEntity.swift index 1ea5cc98c7..6597b1616e 100644 --- a/submodules/DrawingUI/Sources/DrawingTextEntity.swift +++ b/submodules/DrawingUI/Sources/DrawingTextEntity.swift @@ -6,6 +6,8 @@ import AccountContext import TextFormat import EmojiTextAttachmentView import MediaEditor +import MobileCoreServices +import ImageTransparency extension DrawingTextEntity.Alignment { var alignment: NSTextAlignment { @@ -30,6 +32,7 @@ public final class DrawingTextEntityView: DrawingEntityView, UITextViewDelegate var emojiViewProvider: ((ChatTextInputTextCustomEmojiAttribute) -> UIView)? var textChanged: () -> Void = {} + var replaceWithImage: (UIImage, Bool) -> Void = { _, _ in } init(context: AccountContext, entity: DrawingTextEntity) { self.textView = DrawingTextView(frame: .zero) @@ -64,6 +67,10 @@ public final class DrawingTextEntityView: DrawingEntityView, UITextViewDelegate return EmojiTextAttachmentView(context: context, userLocation: .other, emoji: emoji, file: emoji.file, cache: strongSelf.context.animationCache, renderer: strongSelf.context.animationRenderer, placeholderColor: UIColor.white.withAlphaComponent(0.12), pointSize: CGSize(width: pointSize, height: pointSize)) } + self.textView.onPaste = { [weak self] in + return self?.onPaste() ?? false + } + self.update(animated: false) } @@ -88,6 +95,52 @@ public final class DrawingTextEntityView: DrawingEntityView, UITextViewDelegate self.endEditing() } + private func onPaste() -> Bool { + let pasteboard = UIPasteboard.general + + var images: [UIImage] = [] + var isPNG = false + var isMemoji = false + for item in pasteboard.items { + if let image = item["com.apple.png-sticker"] as? UIImage { + images.append(image) + isPNG = true + isMemoji = true + } else if let image = item[kUTTypePNG as String] as? UIImage { + images.append(image) + isPNG = true + } else if let image = item["com.apple.uikit.image"] as? UIImage { + images.append(image) + isPNG = true + } else if let image = item[kUTTypeJPEG as String] as? UIImage { + images.append(image) + } else if let image = item[kUTTypeGIF as String] as? UIImage { + images.append(image) + } + } + + if isPNG && images.count == 1, let image = images.first, let cgImage = image.cgImage { + let maxSide = max(image.size.width, image.size.height) + if maxSide.isZero { + return false + } + let aspectRatio = min(image.size.width, image.size.height) / maxSide + if isMemoji || (imageHasTransparency(cgImage) && aspectRatio > 0.2) { + self.endEditing(reset: true) + self.replaceWithImage(image, true) + return false + } + } + + if !images.isEmpty, let image = images.first { + self.endEditing(reset: true) + self.replaceWithImage(image, false) + return false + } + + return true + } + private var emojiRects: [(CGRect, ChatTextInputTextCustomEmojiAttribute)] = [] func updateEntities() { self.textView.drawingLayoutManager.ensureLayout(for: self.textView.textContainer) @@ -1270,12 +1323,6 @@ final class DrawingTextView: UITextView, NSLayoutManagerDelegate { self.fixTypingAttributes() } - override func paste(_ sender: Any?) { - self.fixTypingAttributes() - super.paste(sender) - self.fixTypingAttributes() - } - fileprivate func fixTypingAttributes() { var attributes: [NSAttributedString.Key: Any] = [:] if let font = self.font { @@ -1347,6 +1394,29 @@ final class DrawingTextView: UITextView, NSLayoutManagerDelegate { self.onLayersUpdate?() } + + var onPaste: () -> Bool = { return true } + override func paste(_ sender: Any?) { + if !self.text.isEmpty || self.onPaste() { + self.fixTypingAttributes() + super.paste(sender) + self.fixTypingAttributes() + } + } + + override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool { + if action == #selector(self.paste(_:)) { + if UIPasteboard.general.hasImages && self.text.isEmpty { + return true + } + } + if #available(iOS 15.0, *) { + if action == #selector(captureTextFromCamera(_:)) { + return false + } + } + return super.canPerformAction(action, withSender: sender) + } } private var availableFonts: [String: (String, String)] = { diff --git a/submodules/TelegramUI/Components/MediaEditor/Sources/Drawing/DrawingTextEntity.swift b/submodules/TelegramUI/Components/MediaEditor/Sources/Drawing/DrawingTextEntity.swift index e77f711caf..af589e6759 100644 --- a/submodules/TelegramUI/Components/MediaEditor/Sources/Drawing/DrawingTextEntity.swift +++ b/submodules/TelegramUI/Components/MediaEditor/Sources/Drawing/DrawingTextEntity.swift @@ -302,22 +302,4 @@ public final class DrawingTextEntity: DrawingEntity, Codable { } return true } - -// public weak var currentEntityView: DrawingEntityView? -// public func makeView(context: AccountContext) -> DrawingEntityView { -// let entityView = DrawingTextEntityView(context: context, entity: self) -// self.currentEntityView = entityView -// return entityView -// } -// -// public func prepareForRender() { -// self.renderImage = (self.currentEntityView as? DrawingTextEntityView)?.getRenderImage() -// self.renderSubEntities = (self.currentEntityView as? DrawingTextEntityView)?.getRenderSubEntities() -// -// if case .none = self.animation { -// self.renderAnimationFrames = nil -// } else { -// self.renderAnimationFrames = (self.currentEntityView as? DrawingTextEntityView)?.getRenderAnimationFrames() -// } -// } } diff --git a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaToolsScreen.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaToolsScreen.swift index 28b084dbaa..551b50ca83 100644 --- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaToolsScreen.swift +++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaToolsScreen.swift @@ -646,15 +646,15 @@ private final class MediaToolsScreenComponent: Component { minValue: 0.0, maxValue: 1.0, startValue: 0.0 - ), - AdjustmentTool( - key: .sharpen, - title: "Sharpen", - value: mediaEditor?.getToolValue(.sharpen) as? Float ?? 0.0, - minValue: 0.0, - maxValue: 1.0, - startValue: 0.0 ) +// AdjustmentTool( +// key: .sharpen, +// title: "Sharpen", +// value: mediaEditor?.getToolValue(.sharpen) as? Float ?? 0.0, +// minValue: 0.0, +// maxValue: 1.0, +// startValue: 0.0 +// ) ] if !component.mediaEditor.sourceIsVideo { diff --git a/submodules/TelegramUI/Components/TextFieldComponent/Sources/TextFieldComponent.swift b/submodules/TelegramUI/Components/TextFieldComponent/Sources/TextFieldComponent.swift index 2c69d927b7..c953ce79b3 100644 --- a/submodules/TelegramUI/Components/TextFieldComponent/Sources/TextFieldComponent.swift +++ b/submodules/TelegramUI/Components/TextFieldComponent/Sources/TextFieldComponent.swift @@ -287,7 +287,6 @@ public final class TextFieldComponent: Component { return false } - var images: [UIImage] = [] if let data = pasteboard.data(forPasteboardType: "com.compuserve.gif") { component.paste(.gif(data)) return false @@ -295,6 +294,7 @@ public final class TextFieldComponent: Component { component.paste(.video(data)) return false } else { + var images: [UIImage] = [] var isPNG = false var isMemoji = false for item in pasteboard.items { @@ -332,6 +332,7 @@ public final class TextFieldComponent: Component { return false } } + return true }