mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-04 21:41:45 +00:00
Glass
This commit is contained in:
parent
f5ca87fb23
commit
5728de8df8
@ -66,7 +66,10 @@ public let chatTextInputMinFontSize: CGFloat = 5.0
|
||||
private let minInputFontSize = chatTextInputMinFontSize
|
||||
|
||||
private func calclulateTextFieldMinHeight(_ presentationInterfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat {
|
||||
let baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
var baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
if "".isEmpty {
|
||||
baseFontSize = 17.0
|
||||
}
|
||||
var result: CGFloat
|
||||
if baseFontSize.isEqual(to: 26.0) {
|
||||
result = 42.0
|
||||
@ -82,15 +85,14 @@ private func calclulateTextFieldMinHeight(_ presentationInterfaceState: ChatPres
|
||||
result = 31.0
|
||||
}
|
||||
|
||||
if case .regular = metrics.widthClass {
|
||||
result = max(33.0, result)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private func calculateTextFieldRealInsets(presentationInterfaceState: ChatPresentationInterfaceState, accessoryButtonsWidth: CGFloat) -> UIEdgeInsets {
|
||||
let baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
var baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
if "".isEmpty {
|
||||
baseFontSize = 17.0
|
||||
}
|
||||
let top: CGFloat
|
||||
let bottom: CGFloat
|
||||
if baseFontSize.isEqual(to: 14.0) {
|
||||
@ -452,6 +454,9 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
textColor = presentationInterfaceState.theme.chat.inputPanel.inputTextColor
|
||||
baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
}
|
||||
if "".isEmpty {
|
||||
baseFontSize = 17.0
|
||||
}
|
||||
textInputNode.attributedText = NSAttributedString(string: value, font: Font.regular(baseFontSize), textColor: textColor)
|
||||
self.chatInputTextNodeDidUpdateText()
|
||||
}
|
||||
@ -1038,7 +1043,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
|
||||
var accessoryButtonsWidth: CGFloat = 0.0
|
||||
var firstButton = true
|
||||
for (_, button) in self.accessoryItemButtons {
|
||||
for (item, button) in self.accessoryItemButtons {
|
||||
if firstButton {
|
||||
firstButton = false
|
||||
accessoryButtonsWidth += self.accessoryButtonInset
|
||||
@ -1046,6 +1051,12 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
accessoryButtonsWidth += self.accessoryButtonSpacing
|
||||
}
|
||||
accessoryButtonsWidth += button.buttonWidth
|
||||
switch item {
|
||||
case .input:
|
||||
accessoryButtonsWidth -= 2.0
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var textFieldMinHeight: CGFloat = 35.0
|
||||
@ -1081,11 +1092,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
}
|
||||
|
||||
private func textFieldInsets(metrics: LayoutMetrics) -> UIEdgeInsets {
|
||||
var insets = UIEdgeInsets(top: 0.0, left: 54.0, bottom: 0.0, right: 54.0)
|
||||
if case .regular = metrics.widthClass, case .regular = metrics.heightClass {
|
||||
insets.top += 1.0
|
||||
insets.bottom += 1.0
|
||||
}
|
||||
let insets = UIEdgeInsets(top: 0.0, left: 54.0, bottom: 0.0, right: 54.0)
|
||||
return insets
|
||||
}
|
||||
|
||||
@ -1097,10 +1104,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
|
||||
override public func minimalHeight(interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat {
|
||||
let textFieldMinHeight = calclulateTextFieldMinHeight(interfaceState, metrics: metrics)
|
||||
var minimalHeight: CGFloat = 14.0 + textFieldMinHeight
|
||||
if case .regular = metrics.widthClass, case .regular = metrics.heightClass {
|
||||
minimalHeight += 2.0
|
||||
}
|
||||
let minimalHeight: CGFloat = 14.0 + textFieldMinHeight
|
||||
return minimalHeight
|
||||
}
|
||||
|
||||
@ -1563,7 +1567,10 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
|
||||
if self.theme == nil || !self.theme!.chat.inputPanel.inputTextColor.isEqual(interfaceState.theme.chat.inputPanel.inputTextColor) {
|
||||
let textColor = interfaceState.theme.chat.inputPanel.inputTextColor
|
||||
let baseFontSize = max(minInputFontSize, interfaceState.fontSize.baseDisplaySize)
|
||||
var baseFontSize = max(minInputFontSize, interfaceState.fontSize.baseDisplaySize)
|
||||
if "".isEmpty {
|
||||
baseFontSize = 17.0
|
||||
}
|
||||
|
||||
if let textInputNode = self.textInputNode {
|
||||
if let text = textInputNode.attributedText {
|
||||
@ -2505,6 +2512,12 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
transition.updateAlpha(layer: button.layer, alpha: audioRecordingItemsAlpha)
|
||||
nextButtonTopRight.x -= buttonSize.width
|
||||
nextButtonTopRight.x -= accessoryButtonSpacing
|
||||
switch item.key {
|
||||
case .input:
|
||||
nextButtonTopRight.x += 2.0
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
let textInputBackgroundFrame = CGRect(x: hideOffset.x + leftInset + textFieldInsets.left, y: hideOffset.y + textFieldInsets.top + textFieldTopContentOffset, width: baseWidth - textFieldInsets.left - textFieldInsets.right, height: panelHeight - textFieldInsets.top - textFieldInsets.bottom + self.textInputViewInternalInsets.top + self.textInputViewInternalInsets.bottom)
|
||||
@ -2518,7 +2531,10 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
if (updatedPlaceholder != nil && self.currentPlaceholder != updatedPlaceholder) || themeUpdated {
|
||||
let currentPlaceholder = updatedPlaceholder ?? self.currentPlaceholder ?? ""
|
||||
self.currentPlaceholder = currentPlaceholder
|
||||
let baseFontSize = max(minInputFontSize, interfaceState.fontSize.baseDisplaySize)
|
||||
var baseFontSize = max(minInputFontSize, interfaceState.fontSize.baseDisplaySize)
|
||||
if "".isEmpty {
|
||||
baseFontSize = 17.0
|
||||
}
|
||||
|
||||
let attributedPlaceholder = NSMutableAttributedString(string: currentPlaceholder, font: Font.regular(baseFontSize), textColor: placeholderColor.withAlphaComponent(1.0))
|
||||
if placeholderHasStar, let range = attributedPlaceholder.string.range(of: "#") {
|
||||
@ -2923,7 +2939,10 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
var rects: [CGRect] = []
|
||||
var customEmojiRects: [(CGRect, ChatTextInputTextCustomEmojiAttribute, CGFloat)] = []
|
||||
|
||||
let fontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
var fontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
if "".isEmpty {
|
||||
fontSize = 17.0
|
||||
}
|
||||
|
||||
if let attributedText = textInputNode.attributedText {
|
||||
let beginning = textInputNode.textView.beginningOfDocument
|
||||
@ -3949,7 +3968,10 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
self.inputMenu.hide()
|
||||
}
|
||||
|
||||
let baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
var baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
if "".isEmpty {
|
||||
baseFontSize = 17.0
|
||||
}
|
||||
refreshChatTextInputTypingAttributes(textInputNode.textView, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize)
|
||||
|
||||
self.updateSpoilersRevealed()
|
||||
@ -4338,6 +4360,9 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
textColor = presentationInterfaceState.theme.chat.inputPanel.inputTextColor
|
||||
accentTextColor = presentationInterfaceState.theme.chat.inputPanel.panelControlAccentColor
|
||||
baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
if "".isEmpty {
|
||||
baseFontSize = 17.0
|
||||
}
|
||||
}
|
||||
let cleanReplacementString = textAttributedStringForStateText(context: context, stateText: NSAttributedString(string: cleanText), fontSize: baseFontSize, textColor: textColor, accentTextColor: accentTextColor, writingDirection: nil, spoilersRevealed: self.spoilersRevealed, availableEmojis: (self.context?.animatedEmojiStickersValue.keys).flatMap(Set.init) ?? Set(), emojiViewProvider: self.emojiViewProvider, makeCollapsedQuoteAttachment: { text, attributes in
|
||||
return ChatInputTextCollapsedQuoteAttachmentImpl(text: text, attributes: attributes)
|
||||
|
||||
@ -577,7 +577,9 @@ public extension GlassBackgroundView {
|
||||
size.width += inset * 2.0
|
||||
size.height += inset * 2.0
|
||||
|
||||
return generateImage(size, rotatedContext: { size, context in
|
||||
return UIGraphicsImageRenderer(size: size).image { ctx in
|
||||
let context = ctx.cgContext
|
||||
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
func pathApplyingSpread(_ path: CGPath, spread: CGFloat) -> CGPath {
|
||||
@ -606,8 +608,14 @@ public extension GlassBackgroundView {
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
let maskImage = UIGraphicsImageRenderer(size: size).image { ctx in
|
||||
let context = ctx.cgContext
|
||||
context.setFillColor(UIColor.black.cgColor)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(x: inset, y: inset), size: innerSize))
|
||||
}
|
||||
|
||||
let addShadow: (Bool, CGPoint, CGFloat, CGFloat, UIColor, Bool) -> Void = { isOuter, position, blur, spread, shadowColor, isMultiply in
|
||||
let addShadow: (Bool, CGPoint, CGFloat, CGFloat, UIColor, CGBlendMode) -> Void = { isOuter, position, blur, spread, shadowColor, blendMode in
|
||||
var blur = blur
|
||||
blur += abs(spread)
|
||||
|
||||
@ -641,72 +649,119 @@ public extension GlassBackgroundView {
|
||||
context.fillPath()
|
||||
context.setBlendMode(.normal)
|
||||
} else {
|
||||
if let image = generateImage(size, rotatedContext: { size, context in
|
||||
let image = UIGraphicsImageRenderer(size: size).image(actions: { ctx in
|
||||
let context = ctx.cgContext
|
||||
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
let spreadRect = CGRect(origin: CGPoint(x: inset, y: inset), size: innerSize).insetBy(dx: -0.25, dy: -0.25)
|
||||
let spreadRect = CGRect(origin: CGPoint(x: inset, y: inset), size: innerSize).insetBy(dx: -spread - 1.0, dy: -spread - 1.0)
|
||||
let spreadPath = UIBezierPath(
|
||||
roundedRect: spreadRect,
|
||||
cornerRadius: min(spreadRect.width, spreadRect.height) * 0.5
|
||||
).cgPath
|
||||
|
||||
context.setShadow(offset: CGSize(width: position.x, height: position.y), blur: blur, color: shadowColor.cgColor)
|
||||
context.setFillColor(UIColor.black.withAlphaComponent(1.0).cgColor)
|
||||
context.setFillColor(UIColor.red.cgColor)
|
||||
let enclosingRect = spreadRect.insetBy(dx: -10000.0, dy: -10000.0)
|
||||
context.addPath(UIBezierPath(rect: enclosingRect).cgPath)
|
||||
context.addPath(spreadPath)
|
||||
context.fillPath(using: .evenOdd)
|
||||
|
||||
let cleanRect = CGRect(origin: CGPoint(x: inset, y: inset), size: innerSize)
|
||||
let cleanPath = UIBezierPath(
|
||||
roundedRect: cleanRect,
|
||||
cornerRadius: min(cleanRect.width, cleanRect.height) * 0.5
|
||||
).cgPath
|
||||
context.setBlendMode(.copy)
|
||||
context.setFillColor(UIColor.clear.cgColor)
|
||||
context.addPath(UIBezierPath(rect: enclosingRect).cgPath)
|
||||
context.addPath(cleanPath)
|
||||
context.fillPath(using: .evenOdd)
|
||||
context.setBlendMode(.normal)
|
||||
}) {
|
||||
UIGraphicsPushContext(context)
|
||||
image.draw(in: CGRect(origin: .zero, size: size), blendMode: isMultiply ? .destinationOut : .normal, alpha: 1.0)
|
||||
UIGraphicsPopContext()
|
||||
}
|
||||
maskImage.draw(at: CGPoint(), blendMode: .destinationIn, alpha: 1.0)
|
||||
})
|
||||
|
||||
UIGraphicsPushContext(context)
|
||||
image.draw(in: CGRect(origin: .zero, size: size), blendMode: blendMode, alpha: 1.0)
|
||||
UIGraphicsPopContext()
|
||||
}
|
||||
}
|
||||
|
||||
if isDark {
|
||||
addShadow(true, CGPoint(), 16.0, 0.0, UIColor(white: 0.0, alpha: 0.12), false)
|
||||
addShadow(true, CGPoint(), 8.0, 0.0, UIColor(white: 0.0, alpha: 0.1), false)
|
||||
|
||||
context.setFillColor(fillColor.cgColor)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: inset, dy: inset))
|
||||
|
||||
addShadow(false, CGPoint(x: 0.0, y: 0.0), 3.0, 0.0, UIColor(white: 1.0, alpha: 0.25), false)
|
||||
addShadow(false, CGPoint(x: 2.0, y: -2.0), 1.0, 0.0, UIColor(white: 1.0, alpha: 0.125), false)
|
||||
addShadow(false, CGPoint(x: -2.0, y: 2.0), 1.0, 0.0, UIColor(white: 1.0, alpha: 0.125), false)
|
||||
} else {
|
||||
addShadow(true, CGPoint(), 16.0, 0.0, UIColor(white: 0.0, alpha: 0.08), false)
|
||||
|
||||
context.setFillColor(fillColor.cgColor)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: inset, dy: inset))
|
||||
|
||||
let highlightColor: UIColor
|
||||
if fillColor.hsb.s > 0.5 {
|
||||
var (h, s, v) = fillColor.hsb
|
||||
s = max(0.0, min(1.0, s * 0.25))
|
||||
v = max(v, 0.95)
|
||||
h = max(0.0, min(1.0, h - 0.1))
|
||||
|
||||
highlightColor = UIColor(hue: h, saturation: s, brightness: v, alpha: fillColor.alpha)
|
||||
} else {
|
||||
highlightColor = UIColor(white: 1.0, alpha: min(1.0, fillColor.alpha * 1.2))
|
||||
addShadow(true, CGPoint(), 16.0, 0.0, UIColor(white: 0.0, alpha: 0.08), .normal)
|
||||
|
||||
context.setFillColor(fillColor.cgColor)
|
||||
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: inset, dy: inset).insetBy(dx: 0.1, dy: 0.1))
|
||||
|
||||
/*
|
||||
case normal = 0
|
||||
|
||||
case multiply = 1
|
||||
|
||||
case screen = 2
|
||||
|
||||
case overlay = 3
|
||||
|
||||
case darken = 4
|
||||
|
||||
case lighten = 5
|
||||
|
||||
case colorDodge = 6
|
||||
|
||||
case colorBurn = 7
|
||||
|
||||
case softLight = 8
|
||||
|
||||
case hardLight = 9
|
||||
|
||||
case difference = 10
|
||||
|
||||
case exclusion = 11
|
||||
|
||||
case hue = 12
|
||||
|
||||
case saturation = 13
|
||||
|
||||
case color = 14
|
||||
|
||||
case luminosity = 15
|
||||
|
||||
case clear = 16
|
||||
|
||||
case copy = 17
|
||||
|
||||
case sourceIn = 18
|
||||
|
||||
case sourceOut = 19
|
||||
|
||||
case sourceAtop = 20
|
||||
|
||||
case destinationOver = 21
|
||||
|
||||
case destinationIn = 22
|
||||
|
||||
case destinationOut = 23
|
||||
|
||||
case destinationAtop = 24
|
||||
|
||||
case xor = 25
|
||||
|
||||
case plusDarker = 26
|
||||
|
||||
case plusLighter = 27
|
||||
*/
|
||||
|
||||
var a: CGFloat = 0.0
|
||||
var b: CGFloat = 0.0
|
||||
fillColor.getHue(nil, saturation: nil, brightness: &b, alpha: &a)
|
||||
|
||||
addShadow(true, CGPoint(x: 0.0, y: 0.0), 20.0, 0.0, UIColor(white: 0.0, alpha: 0.04), .normal)
|
||||
addShadow(true, CGPoint(x: 0.0, y: 0.0), 5.0, 0.0, UIColor(white: 0.0, alpha: 0.04), .normal)
|
||||
|
||||
let edgeWidth: CGFloat = 0.5
|
||||
let edgeAlpha: CGFloat = max(0.2, min(0.8, a * a * a))
|
||||
|
||||
if b >= 0.2 {
|
||||
for _ in 0 ..< 3 {
|
||||
addShadow(false, CGPoint(x: 0.0, y: 0.0), 1.0, 0.0, UIColor(white: 1.0, alpha: edgeAlpha), .overlay)
|
||||
addShadow(false, CGPoint(x: edgeWidth, y: edgeWidth), 1.4, 0.0, UIColor(white: 1.0, alpha: edgeAlpha * 0.9), .overlay)
|
||||
addShadow(false, CGPoint(x: -edgeWidth, y: -edgeWidth), 1.4, 0.0, UIColor(white: 1.0, alpha: edgeAlpha * 0.9), .overlay)
|
||||
}
|
||||
} else {
|
||||
for _ in 0 ..< 3 {
|
||||
addShadow(false, CGPoint(x: 0.0, y: 0.0), 1.0, 0.0, UIColor(white: 1.0, alpha: edgeAlpha), .normal)
|
||||
addShadow(false, CGPoint(x: edgeWidth, y: edgeWidth), 1.4, 0.0, UIColor(white: 1.0, alpha: edgeAlpha * 0.9), .normal)
|
||||
addShadow(false, CGPoint(x: -edgeWidth, y: -edgeWidth), 1.4, 0.0, UIColor(white: 1.0, alpha: edgeAlpha * 0.9), .normal)
|
||||
}
|
||||
|
||||
addShadow(false, CGPoint(x: 2.0, y: -2.0), 1.0, 0.0, highlightColor, false)
|
||||
addShadow(false, CGPoint(x: -2.0, y: 2.0), 1.0, 0.0, highlightColor, false)
|
||||
}
|
||||
})!.stretchableImage(withLeftCapWidth: Int(size.width * 0.5), topCapHeight: Int(size.height * 0.5))
|
||||
}.stretchableImage(withLeftCapWidth: Int(size.width * 0.5), topCapHeight: Int(size.height * 0.5))
|
||||
}
|
||||
|
||||
static func generateForegroundImage(size: CGSize, isDark: Bool, fillColor: UIColor) -> UIImage {
|
||||
|
||||
@ -3784,11 +3784,15 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
}
|
||||
self.searchNavigationNode?.deactivate()
|
||||
|
||||
self.view.window?.endEditing(true)
|
||||
if let firstResponder = self.view.window?.findFirstResponder() {
|
||||
firstResponder.resignFirstResponder()
|
||||
}
|
||||
}
|
||||
|
||||
func dismissTextInput() {
|
||||
self.view.window?.endEditing(true)
|
||||
if let firstResponder = self.view.window?.findFirstResponder() {
|
||||
firstResponder.resignFirstResponder()
|
||||
}
|
||||
}
|
||||
|
||||
func collapseInput() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user