mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Various Improvements
This commit is contained in:
@@ -51,7 +51,7 @@ public final class ContextMenuContainerNode: ASDisplayNode {
|
||||
let maskParams = CachedMaskParams(size: self.bounds.size, relativeArrowPosition: self.relativeArrowPosition?.0 ?? self.bounds.size.width / 2.0, arrowOnBottom: self.relativeArrowPosition?.1 ?? true)
|
||||
if self.cachedMaskParams != maskParams {
|
||||
let path = UIBezierPath()
|
||||
let cornerRadius: CGFloat = 6.0
|
||||
let cornerRadius: CGFloat = 10.0
|
||||
let verticalInset: CGFloat = 9.0
|
||||
let arrowWidth: CGFloat = 18.0
|
||||
let requestedArrowPosition = maskParams.relativeArrowPosition
|
||||
|
||||
@@ -3,10 +3,16 @@ import UIKit
|
||||
import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
|
||||
public protocol TooltipControllerCustomContentNode: ASDisplayNode {
|
||||
func animateIn()
|
||||
func updateLayout(size: CGSize) -> CGSize
|
||||
}
|
||||
|
||||
public enum TooltipControllerContent: Equatable {
|
||||
case text(String)
|
||||
case attributedText(NSAttributedString)
|
||||
case iconAndText(UIImage, String)
|
||||
case custom(TooltipControllerCustomContentNode)
|
||||
|
||||
var text: String {
|
||||
switch self {
|
||||
@@ -14,6 +20,8 @@ public enum TooltipControllerContent: Equatable {
|
||||
return text
|
||||
case let .attributedText(text):
|
||||
return text.string
|
||||
case .custom:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +31,35 @@ public enum TooltipControllerContent: Equatable {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public static func == (lhs: TooltipControllerContent, rhs: TooltipControllerContent) -> Bool {
|
||||
switch lhs {
|
||||
case let .text(lhsText):
|
||||
if case let .text(rhsText) = rhs, lhsText == rhsText {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .attributedText(lhsText):
|
||||
if case let .attributedText(rhsText) = rhs, lhsText == rhsText {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .iconAndText(_, lhsText):
|
||||
if case let .iconAndText(_, rhsText) = rhs, lhsText == rhsText {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .custom(lhsNode):
|
||||
if case let .custom(rhsNode) = rhs, lhsNode === rhsNode {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum SourceAndRect {
|
||||
|
||||
@@ -12,6 +12,7 @@ final class TooltipControllerNode: ASDisplayNode {
|
||||
private let containerNode: ContextMenuContainerNode
|
||||
private let imageNode: ASImageNode
|
||||
private let textNode: ImmediateTextNode
|
||||
private var contentNode: TooltipControllerCustomContentNode?
|
||||
|
||||
private let dismissByTapOutside: Bool
|
||||
|
||||
@@ -45,10 +46,15 @@ final class TooltipControllerNode: ASDisplayNode {
|
||||
|
||||
self.dismiss = dismiss
|
||||
|
||||
if case let .custom(contentNode) = content {
|
||||
self.contentNode = contentNode
|
||||
}
|
||||
|
||||
super.init()
|
||||
|
||||
self.containerNode.addSubnode(self.imageNode)
|
||||
self.containerNode.addSubnode(self.textNode)
|
||||
self.contentNode.flatMap { self.containerNode.addSubnode($0) }
|
||||
|
||||
self.addSubnode(self.containerNode)
|
||||
}
|
||||
@@ -71,20 +77,37 @@ final class TooltipControllerNode: ASDisplayNode {
|
||||
func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||
self.validLayout = layout
|
||||
|
||||
let maxActionsWidth = layout.size.width - 20.0
|
||||
let maxWidth = layout.size.width - 20.0
|
||||
|
||||
var imageSize = CGSize()
|
||||
var imageSizeWithInset = CGSize()
|
||||
if let image = self.imageNode.image {
|
||||
imageSize = image.size
|
||||
imageSizeWithInset = CGSize(width: image.size.width + 12.0, height: image.size.height)
|
||||
let contentSize: CGSize
|
||||
|
||||
if let contentNode = self.contentNode {
|
||||
contentSize = contentNode.updateLayout(size: layout.size)
|
||||
contentNode.frame = CGRect(origin: CGPoint(), size: contentSize)
|
||||
} else {
|
||||
var imageSize = CGSize()
|
||||
var imageSizeWithInset = CGSize()
|
||||
if let image = self.imageNode.image {
|
||||
imageSize = image.size
|
||||
imageSizeWithInset = CGSize(width: image.size.width + 12.0, height: image.size.height)
|
||||
}
|
||||
|
||||
var textSize = self.textNode.updateLayout(CGSize(width: maxWidth, height: CGFloat.greatestFiniteMagnitude))
|
||||
textSize.width = ceil(textSize.width / 2.0) * 2.0
|
||||
textSize.height = ceil(textSize.height / 2.0) * 2.0
|
||||
|
||||
contentSize = CGSize(width: imageSizeWithInset.width + textSize.width + 12.0, height: textSize.height + 34.0)
|
||||
|
||||
let textFrame = CGRect(origin: CGPoint(x: 6.0 + imageSizeWithInset.width, y: 17.0), size: textSize)
|
||||
if transition.isAnimated, textFrame.size != self.textNode.frame.size {
|
||||
transition.animatePositionAdditive(node: self.textNode, offset: CGPoint(x: textFrame.minX - self.textNode.frame.minX, y: 0.0))
|
||||
}
|
||||
|
||||
let imageFrame = CGRect(origin: CGPoint(x: 10.0, y: floor((contentSize.height - imageSize.height) / 2.0)), size: imageSize)
|
||||
self.imageNode.frame = imageFrame
|
||||
self.textNode.frame = textFrame
|
||||
}
|
||||
|
||||
var textSize = self.textNode.updateLayout(CGSize(width: maxActionsWidth, height: CGFloat.greatestFiniteMagnitude))
|
||||
textSize.width = ceil(textSize.width / 2.0) * 2.0
|
||||
textSize.height = ceil(textSize.height / 2.0) * 2.0
|
||||
let contentSize = CGSize(width: imageSizeWithInset.width + textSize.width + 12.0, height: textSize.height + 34.0)
|
||||
|
||||
|
||||
let sourceRect: CGRect = self.sourceRect ?? CGRect(origin: CGPoint(x: layout.size.width / 2.0, y: layout.size.height / 2.0), size: CGSize())
|
||||
|
||||
let insets = layout.insets(options: [.statusBar, .input])
|
||||
@@ -105,19 +128,11 @@ final class TooltipControllerNode: ASDisplayNode {
|
||||
self.containerNode.relativeArrowPosition = (sourceRect.midX - horizontalOrigin, arrowOnBottom)
|
||||
|
||||
self.containerNode.updateLayout(transition: transition)
|
||||
|
||||
let textFrame = CGRect(origin: CGPoint(x: 6.0 + imageSizeWithInset.width, y: 17.0), size: textSize)
|
||||
if transition.isAnimated, textFrame.size != self.textNode.frame.size {
|
||||
transition.animatePositionAdditive(node: self.textNode, offset: CGPoint(x: textFrame.minX - self.textNode.frame.minX, y: 0.0))
|
||||
}
|
||||
|
||||
let imageFrame = CGRect(origin: CGPoint(x: 10.0, y: floor((contentSize.height - imageSize.height) / 2.0)), size: imageSize)
|
||||
self.imageNode.frame = imageFrame
|
||||
self.textNode.frame = textFrame
|
||||
}
|
||||
|
||||
func animateIn() {
|
||||
self.containerNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
|
||||
self.contentNode?.animateIn()
|
||||
}
|
||||
|
||||
func animateOut(completion: @escaping () -> Void) {
|
||||
|
||||
Reference in New Issue
Block a user