Various improvements

This commit is contained in:
Ilya Laktyushin
2024-06-07 14:07:01 +04:00
parent 5470ba80ec
commit 1cc27e2a20
14 changed files with 281 additions and 331 deletions

View File

@@ -15,7 +15,9 @@ final private class ContextMenuActionButton: HighlightTrackingButton {
final class ContextMenuActionNode: ASDisplayNode {
private let textNode: ImmediateTextNode?
private let subtitleNode: ImmediateTextNode?
private var textSize: CGSize?
private var subtitleSize: CGSize?
private let iconView: UIImageView?
private let action: () -> Void
private let button: ContextMenuActionButton
@@ -28,37 +30,60 @@ final class ContextMenuActionNode: ASDisplayNode {
self.actionArea.accessibilityTraits = .button
switch action.content {
case let .text(title, accessibilityLabel):
self.actionArea.accessibilityLabel = accessibilityLabel
let textNode = ImmediateTextNode()
textNode.isUserInteractionEnabled = false
textNode.displaysAsynchronously = false
textNode.attributedText = NSAttributedString(string: title, font: Font.regular(14.0), textColor: isDark ? .white : .black)
textNode.isAccessibilityElement = false
self.textNode = textNode
self.iconView = nil
case let .textWithIcon(title, icon):
let textNode = ImmediateTextNode()
textNode.isUserInteractionEnabled = false
textNode.displaysAsynchronously = false
textNode.attributedText = NSAttributedString(string: title, font: Font.regular(17.0), textColor: isDark ? .white : .black)
textNode.isAccessibilityElement = false
case let .text(title, accessibilityLabel):
self.actionArea.accessibilityLabel = accessibilityLabel
let iconView = UIImageView()
iconView.tintColor = isDark ? .white : .black
iconView.image = icon
self.textNode = textNode
self.iconView = iconView
case let .icon(image):
let iconView = UIImageView()
iconView.tintColor = isDark ? .white : .black
iconView.image = image
self.iconView = iconView
self.textNode = nil
let textNode = ImmediateTextNode()
textNode.isUserInteractionEnabled = false
textNode.displaysAsynchronously = false
textNode.attributedText = NSAttributedString(string: title, font: Font.regular(14.0), textColor: isDark ? .white : .black)
textNode.isAccessibilityElement = false
self.textNode = textNode
self.subtitleNode = nil
self.iconView = nil
case let .textWithIcon(title, icon):
let textNode = ImmediateTextNode()
textNode.isUserInteractionEnabled = false
textNode.displaysAsynchronously = false
textNode.attributedText = NSAttributedString(string: title, font: Font.regular(17.0), textColor: isDark ? .white : .black)
textNode.isAccessibilityElement = false
let iconView = UIImageView()
iconView.tintColor = isDark ? .white : .black
iconView.image = icon
self.textNode = textNode
self.subtitleNode = nil
self.iconView = iconView
case let .textWithSubtitleAndIcon(title, subtitle, icon):
let textNode = ImmediateTextNode()
textNode.isUserInteractionEnabled = false
textNode.displaysAsynchronously = false
textNode.attributedText = NSAttributedString(string: title, font: Font.regular(17.0), textColor: isDark ? .white : .black)
textNode.isAccessibilityElement = false
let subtitleNode = ImmediateTextNode()
subtitleNode.isUserInteractionEnabled = false
subtitleNode.displaysAsynchronously = false
subtitleNode.attributedText = NSAttributedString(string: subtitle, font: Font.regular(12.0), textColor: (isDark ? UIColor.white : UIColor.black).withAlphaComponent(0.5))
subtitleNode.isAccessibilityElement = false
let iconView = UIImageView()
iconView.tintColor = isDark ? .white : .black
iconView.image = icon
self.textNode = textNode
self.subtitleNode = subtitleNode
self.iconView = iconView
case let .icon(image):
let iconView = UIImageView()
iconView.tintColor = isDark ? .white : .black
iconView.image = image
self.iconView = iconView
self.textNode = nil
self.subtitleNode = nil
}
self.action = action.action
@@ -74,6 +99,9 @@ final class ContextMenuActionNode: ASDisplayNode {
if let textNode = self.textNode {
self.addSubnode(textNode)
}
if let subtitleNode = self.subtitleNode {
self.addSubnode(subtitleNode)
}
if let iconView = self.iconView {
self.view.addSubview(iconView)
}
@@ -119,7 +147,16 @@ final class ContextMenuActionNode: ASDisplayNode {
self.textSize = textSize
var totalWidth = 0.0
var totalHeight: CGFloat = 54.0
totalWidth += textSize.width
if let subtitleNode = self.subtitleNode {
let subtitleSize = subtitleNode.updateLayout(constrainedSize)
self.subtitleSize = subtitleSize
totalWidth = max(totalWidth, subtitleSize.width)
totalHeight += 14.0
}
if let image = self.iconView?.image {
if totalWidth > 0.0 {
totalWidth += 11.0
@@ -130,7 +167,7 @@ final class ContextMenuActionNode: ASDisplayNode {
totalWidth += 36.0
}
return CGSize(width: totalWidth, height: 54.0)
return CGSize(width: totalWidth, height: totalHeight)
} else if let iconView = self.iconView, let image = iconView.image {
return CGSize(width: image.size.width + 36.0, height: 54.0)
} else {
@@ -148,6 +185,9 @@ final class ContextMenuActionNode: ASDisplayNode {
if let textSize = self.textSize {
totalWidth += textSize.width
}
if let subtitleSize = self.subtitleSize {
totalWidth = max(totalWidth, subtitleSize.width)
}
if let image = self.iconView?.image {
if totalWidth > 0.0 {
totalWidth += 11.0
@@ -155,8 +195,18 @@ final class ContextMenuActionNode: ASDisplayNode {
totalWidth += image.size.width
}
var totalTextHeight: CGFloat = 0.0
if let textSize = self.textSize {
totalTextHeight += textSize.height
}
if let subtitleSize = self.subtitleSize {
totalTextHeight += subtitleSize.height
}
if let textNode = self.textNode, let textSize = self.textSize {
textNode.frame = CGRect(origin: CGPoint(x: floor((self.bounds.size.width - totalWidth) / 2.0), y: floor((self.bounds.size.height - textSize.height) / 2.0)), size: textSize)
textNode.frame = CGRect(origin: CGPoint(x: floor((self.bounds.size.width - totalWidth) / 2.0), y: floor((self.bounds.size.height - totalTextHeight) / 2.0)), size: textSize)
}
if let subtitleNode = self.subtitleNode, let subtitleSize = self.subtitleSize {
subtitleNode.frame = CGRect(origin: CGPoint(x: floor((self.bounds.size.width - totalWidth) / 2.0), y: floor((self.bounds.size.height - totalTextHeight) / 2.0) + totalTextHeight - subtitleSize.height), size: subtitleSize)
}
if let iconView = self.iconView, let image = iconView.image {
let iconSize = image.size

View File

@@ -175,12 +175,11 @@ final class ContextMenuNode: ASDisplayNode {
let separatorColor = self.isDark ? UIColor(rgb: 0x8c8e8e) : UIColor(rgb: 0xDCE3DC)
let height: CGFloat = 54.0
var height: CGFloat = 54.0
let pageLeftSize = self.pageLeftNode.update(color: self.isDark ? .white : .black, separatorColor: separatorColor, height: height)
let pageRightSize = self.pageRightNode.update(color: self.isDark ? .white : .black, separatorColor: separatorColor, height: height)
let maxPageWidth = layout.size.width - 20.0 - pageLeftSize.width - pageRightSize.width
let handleWidth: CGFloat = 33.0
let maxPageWidth = layout.size.width - 20.0 - handleWidth * 2.0
var absoluteActionOffsetX: CGFloat = 0.0
var pages: [Page] = []
@@ -188,7 +187,8 @@ final class ContextMenuNode: ASDisplayNode {
if i != 0 {
absoluteActionOffsetX += UIScreenPixel
}
let actionSize = self.actionNodes[i].measure(CGSize(width: layout.size.width, height: height))
let actionSize = self.actionNodes[i].measure(CGSize(width: layout.size.width, height: 100.0))
height = max(height, actionSize.height)
if pages.isEmpty || (pages[pages.count - 1].width + actionSize.width) > maxPageWidth {
pages.append(Page(range: i ..< (i + 1), width: actionSize.width, offsetX: absoluteActionOffsetX))
} else {
@@ -212,6 +212,9 @@ final class ContextMenuNode: ASDisplayNode {
separatorNode.isHidden = i == self.actionNodes.count - 1
}
let pageLeftSize = self.pageLeftNode.update(color: self.isDark ? .white : .black, separatorColor: separatorColor, height: height)
let pageRightSize = self.pageRightNode.update(color: self.isDark ? .white : .black, separatorColor: separatorColor, height: height)
self.pageCount = pages.count
if !pages.isEmpty {