diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 24ef23a9ce..fe2994a86f 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -8565,6 +8565,12 @@ Sorry for the inconvenience."; "Paint.MoveForward" = "Move Forward"; +"Paint.ColorTitle" = "Colors"; +"Paint.ColorGrid" = "Grid"; +"Paint.ColorSpectrum" = "Spectrum"; +"Paint.ColorSliders" = "Sliders"; +"Paint.ColorOpacity" = "OPACITY"; + "StorageManagement.Title" = "Storage Usage"; "StorageManagement.TitleCleared" = "Storage Cleared"; diff --git a/submodules/DrawingUI/Sources/ColorPickerScreen.swift b/submodules/DrawingUI/Sources/ColorPickerScreen.swift index e22687835a..a1f1d73de2 100644 --- a/submodules/DrawingUI/Sources/ColorPickerScreen.swift +++ b/submodules/DrawingUI/Sources/ColorPickerScreen.swift @@ -2026,6 +2026,8 @@ private final class ColorPickerContent: CombinedComponent { let environment = context.environment[ViewControllerComponentContainer.Environment.self].value let component = context.component let state = context.state + let strings = environment.strings + state.colorChanged = component.colorChanged let sideInset: CGFloat = 16.0 @@ -2079,7 +2081,7 @@ private final class ColorPickerContent: CombinedComponent { let title = title.update( component: MultilineTextComponent( text: .plain(NSAttributedString( - string: "Colors", + string: strings.Paint_ColorTitle, font: Font.semibold(17.0), textColor: .white, paragraphAlignment: .center @@ -2098,7 +2100,7 @@ private final class ColorPickerContent: CombinedComponent { let modeControl = modeControl.update( component: SegmentedControlComponent( - values: ["Grid", "Spectrum", "Sliders"], + values: [strings.Paint_ColorGrid, strings.Paint_ColorSpectrum, strings.Paint_ColorSliders], selectedIndex: 0, selectionChanged: { [weak state] index in state?.updateSelectedMode(index) @@ -2172,7 +2174,7 @@ private final class ColorPickerContent: CombinedComponent { let opacityTitle = opacityTitle.update( component: MultilineTextComponent( text: .plain(NSAttributedString( - string: "OPACITY", + string: strings.Paint_ColorOpacity, font: Font.semibold(13.0), textColor: UIColor(rgb: 0x9b9da5), paragraphAlignment: .center diff --git a/submodules/DrawingUI/Sources/DrawingEntitiesView.swift b/submodules/DrawingUI/Sources/DrawingEntitiesView.swift index d13efe89b4..442c7e6b15 100644 --- a/submodules/DrawingUI/Sources/DrawingEntitiesView.swift +++ b/submodules/DrawingUI/Sources/DrawingEntitiesView.swift @@ -134,6 +134,8 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView { public var getEntityCenterPosition: () -> CGPoint = { return .zero } public var getEntityInitialRotation: () -> CGFloat = { return 0.0 } + public var getEntityAdditionalScale: () -> CGFloat = { return 1.0 } + public var hasSelectionChanged: (Bool) -> Void = { _ in } var selectionChanged: (DrawingEntity?) -> Void = { _ in } var requestedMenuForEntityView: (DrawingEntityView, Bool) -> Void = { _, _ in } diff --git a/submodules/DrawingUI/Sources/DrawingNeonTool.swift b/submodules/DrawingUI/Sources/DrawingNeonTool.swift index 4a3f5aaad3..001b035bcb 100644 --- a/submodules/DrawingUI/Sources/DrawingNeonTool.swift +++ b/submodules/DrawingUI/Sources/DrawingNeonTool.swift @@ -60,8 +60,9 @@ final class NeonTool: DrawingElement { self.layer.addSublayer(self.fillLayer) } - fileprivate func updatePath(_ path: CGPath) { + fileprivate func updatePath(_ path: CGPath, shadowPath: CGPath) { self.shadowLayer.path = path + self.shadowLayer.shadowPath = shadowPath self.borderLayer.path = path self.fillLayer.path = path } @@ -81,6 +82,7 @@ final class NeonTool: DrawingElement { private var addedPaths = 0 fileprivate var renderPath: CGPath? + fileprivate var shadowRenderPath: CGPath? var translation: CGPoint = .zero @@ -91,7 +93,7 @@ final class NeonTool: DrawingElement { } var bounds: CGRect { - if let renderPath = self.renderPath { + if let renderPath = self.shadowRenderPath { return normalizeDrawingRect(renderPath.boundingBoxOfPath.insetBy(dx: -self.renderShadowRadius - 30.0, dy: -self.renderShadowRadius - 30.0), drawingSize: self.drawingSize) } else { return .zero @@ -103,8 +105,8 @@ final class NeonTool: DrawingElement { self.drawingSize = drawingSize self.color = color - let strokeWidth = min(drawingSize.width, drawingSize.height) * 0.01 - let shadowRadius = min(drawingSize.width, drawingSize.height) * 0.03 + let strokeWidth = min(drawingSize.width, drawingSize.height) * 0.008 + let shadowRadius = min(drawingSize.width, drawingSize.height) * 0.02 let minLineWidth = max(1.0, max(drawingSize.width, drawingSize.height) * 0.002) let maxLineWidth = max(10.0, max(drawingSize.width, drawingSize.height) * 0.07) @@ -138,9 +140,11 @@ final class NeonTool: DrawingElement { if let activePath { path?.addPath(activePath.cgPath) } - if let renderPath = path?.copy(strokingWithWidth: self.renderLineWidth, lineCap: .round, lineJoin: .round, miterLimit: 0.0) { + if let renderPath = path?.copy(strokingWithWidth: self.renderLineWidth, lineCap: .round, lineJoin: .round, miterLimit: 0.0), + let shadowRenderPath = path?.copy(strokingWithWidth: self.renderLineWidth * 2.0, lineCap: .round, lineJoin: .round, miterLimit: 0.0) { self.renderPath = renderPath - currentRenderView.updatePath(renderPath) + self.shadowRenderPath = shadowRenderPath + currentRenderView.updatePath(renderPath, shadowPath: shadowRenderPath) } } @@ -155,7 +159,7 @@ final class NeonTool: DrawingElement { } func draw(in context: CGContext, size: CGSize) { - guard let path = self.renderPath else { + guard let path = self.renderPath, let shadowPath = self.shadowRenderPath else { return } context.saveGState() @@ -172,15 +176,20 @@ final class NeonTool: DrawingElement { fillColor = shadowColor shadowColor = UIColor(rgb: 0x440881) } - - context.addPath(path) + + let shadowOffset = CGSize(width: 3000.0, height: 3000.0) + context.translateBy(x: -shadowOffset.width, y: -shadowOffset.height) + + context.addPath(shadowPath) context.setLineCap(.round) context.setFillColor(fillColor.cgColor) context.setStrokeColor(fillColor.cgColor) context.setLineWidth(self.renderStrokeWidth * 0.5) - context.setShadow(offset: .zero, blur: self.renderShadowRadius * 1.9, color: shadowColor.cgColor) + context.setShadow(offset: shadowOffset, blur: self.renderShadowRadius * 1.9, color: shadowColor.withAlphaComponent(0.87).cgColor) context.drawPath(using: .fillStroke) + context.translateBy(x: shadowOffset.width, y: shadowOffset.height) + context.addPath(path) context.setShadow(offset: .zero, blur: 0.0, color: UIColor.clear.cgColor) context.setLineWidth(self.renderStrokeWidth) diff --git a/submodules/DrawingUI/Sources/DrawingPenTool.swift b/submodules/DrawingUI/Sources/DrawingPenTool.swift index 75a30bbc0d..85391730ba 100644 --- a/submodules/DrawingUI/Sources/DrawingPenTool.swift +++ b/submodules/DrawingUI/Sources/DrawingPenTool.swift @@ -2,6 +2,8 @@ import Foundation import UIKit import Display +private let activeWidthFactor: CGFloat = 0.7 + final class PenTool: DrawingElement { class RenderView: UIView, DrawingRenderView { private weak var element: PenTool? @@ -14,7 +16,7 @@ final class PenTool: DrawingElement { private var segmentsCount = 0 private var drawScale = CGSize(width: 1.0, height: 1.0) - + func setup(size: CGSize, screenSize: CGSize, isEraser: Bool) { self.isEraser = isEraser @@ -22,7 +24,6 @@ final class PenTool: DrawingElement { self.isOpaque = false self.contentMode = .redraw - //let scale = CGSize(width: screenSize.width / max(1.0, size.width), height: screenSize.height / max(1.0, size.height)) let scale = CGSize(width: 0.33, height: 0.33) let viewSize = CGSize(width: size.width * scale.width, height: size.height * scale.height) @@ -80,7 +81,26 @@ final class PenTool: DrawingElement { }) } - var displaySize: CGSize? + var onDryingUp: () -> Void = {} + + var isDryingUp = false { + didSet { + if !self.isDryingUp { + self.onDryingUp() + } + } + } + var dryingLayersCount: Int = 0 { + didSet { + if self.dryingLayersCount > 0 { + self.isDryingUp = true + } else { + self.isDryingUp = false + } + } + } + + fileprivate var displaySize: CGSize? fileprivate func draw(element: PenTool, rect: CGRect) { self.element = element @@ -120,15 +140,71 @@ final class PenTool: DrawingElement { self.start = newStart } + if !element.isEraser && !element.isBlur { + let count = CGFloat(element.segments.count - self.segmentsCount) + if count > 0 { + let dryingPath = CGMutablePath() + var abFactor: CGFloat = activeWidthFactor * 1.35 + let delta: CGFloat = (1.0 - abFactor) / count + for i in self.segmentsCount ..< element.segments.count { + let segmentPath = element.pathForSegment(element.segments[i], abFactor: abFactor, cdFactor: abFactor + delta) + dryingPath.addPath(segmentPath) + abFactor += delta + } + self.setupDrying(path: dryingPath) + } + } + self.segmentsCount = element.segments.count if let rect = rect { - self.activeView?.setNeedsDisplay(rect.insetBy(dx: -10.0, dy: -10.0).applying(CGAffineTransform(scaleX: 1.0 / self.drawScale.width, y: 1.0 / self.drawScale.height))) + self.activeView?.setNeedsDisplay(rect.insetBy(dx: -40.0, dy: -40.0).applying(CGAffineTransform(scaleX: 1.0 / self.drawScale.width, y: 1.0 / self.drawScale.height))) } else { self.activeView?.setNeedsDisplay() } } + private let dryingFactor: CGFloat = 0.4 + func setupDrying(path: CGPath) { + guard let element = self.element else { + return + } + + let dryingLayer = CAShapeLayer() + dryingLayer.contentsScale = 1.0 + dryingLayer.fillColor = element.renderColor.cgColor + dryingLayer.strokeColor = element.renderColor.cgColor + dryingLayer.lineWidth = element.renderLineWidth * self.dryingFactor + dryingLayer.path = path + dryingLayer.animate(from: dryingLayer.lineWidth as NSNumber, to: 0.0 as NSNumber, keyPath: "lineWidth", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.4, removeOnCompletion: false, completion: { [weak dryingLayer] _ in + dryingLayer?.removeFromSuperlayer() + self.dryingLayersCount -= 1 + }) + dryingLayer.transform = CATransform3DMakeScale(1.0 / self.drawScale.width, 1.0 / self.drawScale.height, 1.0) + dryingLayer.frame = self.bounds + self.layer.addSublayer(dryingLayer) + + self.dryingLayersCount += 1 + } + + private var isActiveDrying = false + func setupActiveSegmentsDrying() { + guard let element = self.element else { + return + } + + if !element.isEraser && !element.isBlur { + let dryingPath = CGMutablePath() + for segment in element.activeSegments { + let segmentPath = element.pathForSegment(segment) + dryingPath.addPath(segmentPath) + } + self.setupDrying(path: dryingPath) + self.isActiveDrying = true + self.setNeedsDisplay() + } + } + class ActiveView: UIView { weak var parent: RenderView? override func draw(_ rect: CGRect) { @@ -139,7 +215,12 @@ final class PenTool: DrawingElement { parent.displaySize = rect.size context.scaleBy(x: 1.0 / parent.drawScale.width, y: 1.0 / parent.drawScale.height) element.drawSegments(in: context, from: parent.start, to: parent.segmentsCount) - element.drawActiveSegments(in: context) + + if !element.isEraser || !element.isBlur { + element.drawActiveSegments(in: context, strokeWidth: !parent.isActiveDrying ? element.renderLineWidth * parent.dryingFactor : nil) + } else { + element.drawActiveSegments(in: context, strokeWidth: nil) + } } } } @@ -169,6 +250,23 @@ final class PenTool: DrawingElement { var blurredImage: UIImage? private weak var currentRenderView: DrawingRenderView? + + private var points: [Point] = Array(repeating: Point(location: .zero, width: 0.0), count: 4) + private var pointPtr = 0 + + private var smoothPoints: [Point] = [] + private var activeSmoothPoints: [Point] = [] + + private var segments: [Segment] = [] + private var activeSegments: [Segment] = [] + + private var previousActiveRect: CGRect? + + private var previousRenderLineWidth: CGFloat? + + private var segmentPaths: [Int: CGPath] = [:] + + private var useCubicBezier = true var isValid: Bool { if self.hasArrow { @@ -217,7 +315,7 @@ final class PenTool: DrawingElement { completion() } } - + func setupRenderView(screenSize: CGSize) -> DrawingRenderView? { let view = RenderView() view.setup(size: self.drawingSize, screenSize: screenSize, isEraser: self.isEraser) @@ -249,6 +347,8 @@ final class PenTool: DrawingElement { if state == .ended { if !self.activeSegments.isEmpty { + (self.currentRenderView as? RenderView)?.setupActiveSegmentsDrying() + self.segments.append(contentsOf: self.activeSegments) self.smoothPoints.append(contentsOf: self.activeSmoothPoints) } @@ -279,6 +379,9 @@ final class PenTool: DrawingElement { d: CGPoint(x: point.x + radius, y: point.y + 0.1), radius1: radius, radius2: radius, + abCenter: CGPoint(x: point.x, y: point.y), + cdCenter: CGPoint(x: point.x, y: point.y + 0.1), + perpendicular: .zero, rect: CGRect(origin: CGPoint(x: point.x - radius, y: point.y - radius), size: CGSize(width: radius * 2.0, height: radius * 2.0)) ) ) @@ -363,6 +466,9 @@ final class PenTool: DrawingElement { let d: CGPoint let radius1: CGFloat let radius2: CGFloat + let abCenter: CGPoint + let cdCenter: CGPoint + let perpendicular: CGPoint let rect: CGRect init( @@ -372,6 +478,9 @@ final class PenTool: DrawingElement { d: CGPoint, radius1: CGFloat, radius2: CGFloat, + abCenter: CGPoint, + cdCenter: CGPoint, + perpendicular: CGPoint, rect: CGRect ) { self.a = a @@ -380,8 +489,43 @@ final class PenTool: DrawingElement { self.d = d self.radius1 = radius1 self.radius2 = radius2 + self.abCenter = abCenter + self.cdCenter = cdCenter + self.perpendicular = perpendicular self.rect = rect } + + func withMultiplied(abFactor: CGFloat, cdFactor: CGFloat) -> Segment { + let a = CGPoint( + x: self.abCenter.x + self.perpendicular.x * self.radius1 * abFactor, + y: self.abCenter.y + self.perpendicular.y * self.radius1 * abFactor + ) + let b = CGPoint( + x: self.abCenter.x - self.perpendicular.x * self.radius1 * abFactor, + y: self.abCenter.y - self.perpendicular.y * self.radius1 * abFactor + ) + let c = CGPoint( + x: self.cdCenter.x + self.perpendicular.x * self.radius2 * cdFactor, + y: self.cdCenter.y + self.perpendicular.y * self.radius2 * cdFactor + ) + let d = CGPoint( + x: self.cdCenter.x - self.perpendicular.x * self.radius2 * cdFactor, + y: self.cdCenter.y - self.perpendicular.y * self.radius2 * cdFactor + ) + + return Segment( + a: a, + b: b, + c: c, + d: d, + radius1: self.radius1 * abFactor, + radius2: self.radius2 * cdFactor, + abCenter: self.abCenter, + cdCenter: self.cdCenter, + perpendicular: self.perpendicular, + rect: self.rect + ) + } } private struct Point { @@ -396,27 +540,16 @@ final class PenTool: DrawingElement { self.width = width } } - - private var points: [Point] = Array(repeating: Point(location: .zero, width: 0.0), count: 4) - private var pointPtr = 0 - - private var smoothPoints: [Point] = [] - private var activeSmoothPoints: [Point] = [] - - private var segments: [Segment] = [] - private var activeSegments: [Segment] = [] - - private var previousActiveRect: CGRect? - - private var previousRenderLineWidth: CGFloat? - + + private var currentVelocity: CGFloat? private func addPoint(_ point: DrawingPoint, state: DrawingGesturePipeline.DrawingGestureState, zoomScale: CGFloat) -> (Bool, CGRect)? { - let filterDistance: CGFloat = 10.0 / zoomScale + let filterDistance: CGFloat = 8.0 / zoomScale var velocity = point.velocity if velocity.isZero { velocity = 1000.0 } + self.currentVelocity = velocity var renderLineWidth = max(self.renderMinLineWidth, min(self.renderLineWidth - (velocity / 200.0), self.renderLineWidth)) if let previousRenderLineWidth = self.previousRenderLineWidth { @@ -492,9 +625,9 @@ final class PenTool: DrawingElement { private func currentSmoothPoints(_ ctr: Int) -> [Point]? { switch ctr { case 0: - return [self.points[0]] + return nil//return [self.points[0]] case 1: - return self.smoothPoints(.line(self.points[0], self.points[1])) + return nil//return self.smoothPoints(.line(self.points[0], self.points[1])) case 2: return self.smoothPoints(.quad(self.points[0], self.points[1], self.points[2])) case 3: @@ -667,15 +800,29 @@ final class PenTool: DrawingElement { let segmentRect = CGRect(x: minX, y: minY, width: maxX - minX, height: maxY - minY) updateRect = updateRect.union(segmentRect) - let segment = Segment(a: a, b: b, c: c, d: d, radius1: previousWidth / 2.0, radius2: currentWidth / 2.0, rect: segmentRect) + let segment = Segment( + a: a, + b: b, + c: c, + d: d, + radius1: previousWidth / 2.0, + radius2: currentWidth / 2.0, + abCenter: abCenter, + cdCenter: cdCenter, + perpendicular: perpendicular, + rect: segmentRect + ) segments.append(segment) } return (segments, !updateRect.isNull ? updateRect : nil) } - - private var segmentPaths: [Int: CGPath] = [:] - - private func pathForSegment(_ segment: Segment) -> CGPath { + + private func pathForSegment(_ segment: Segment, abFactor: CGFloat = 1.0, cdFactor: CGFloat = 1.0) -> CGPath { + var segment = segment + if abFactor != 1.0 || cdFactor != 1.0 { + segment = segment.withMultiplied(abFactor: abFactor, cdFactor: cdFactor) + } + let path = CGMutablePath() path.move(to: segment.b) @@ -713,6 +860,19 @@ final class PenTool: DrawingElement { return path } + func cachedPathForSegmentIndex(_ i: Int) -> CGPath { + var segmentPath: CGPath + if let current = self.segmentPaths[i] { + segmentPath = current + } else { + let segment = self.segments[i] + let path = self.pathForSegment(segment) + self.segmentPaths[i] = path + segmentPath = path + } + return segmentPath + } + private func drawSegments(in context: CGContext, from: Int, to: Int) { context.setFillColor(self.renderColor.cgColor) @@ -733,13 +893,24 @@ final class PenTool: DrawingElement { } } - private func drawActiveSegments(in context: CGContext) { + private func drawActiveSegments(in context: CGContext, strokeWidth: CGFloat?) { context.setFillColor(self.renderColor.cgColor) + if let strokeWidth { + context.setStrokeColor(self.renderColor.cgColor) + context.setLineWidth(strokeWidth) + } + var abFactor: CGFloat = activeWidthFactor + let delta: CGFloat = (1.0 - activeWidthFactor) / CGFloat(self.activeSegments.count + 1) for segment in self.activeSegments { let path = self.pathForSegment(segment) context.addPath(path) - context.fillPath() + if let _ = strokeWidth { + context.drawPath(using: .fillStroke) + } else { + context.fillPath() + } + abFactor += delta } } } diff --git a/submodules/DrawingUI/Sources/DrawingScreen.swift b/submodules/DrawingUI/Sources/DrawingScreen.swift index edc851263d..7591996476 100644 --- a/submodules/DrawingUI/Sources/DrawingScreen.swift +++ b/submodules/DrawingUI/Sources/DrawingScreen.swift @@ -308,9 +308,11 @@ struct DrawingState: Equatable { final class DrawingSettings: Codable, Equatable { let tools: [DrawingToolState] + let colors: [DrawingColor] - init(tools: [DrawingToolState]) { + init(tools: [DrawingToolState], colors: [DrawingColor]) { self.tools = tools + self.colors = colors } init(from decoder: Decoder) throws { @@ -321,6 +323,12 @@ final class DrawingSettings: Codable, Equatable { } else { self.tools = DrawingState.initial.tools } + + if let data = try container.decodeIfPresent(Data.self, forKey: "colors"), let colors = try? JSONDecoder().decode([DrawingColor].self, from: data) { + self.colors = colors + } else { + self.colors = [] + } } func encode(to encoder: Encoder) throws { @@ -329,10 +337,13 @@ final class DrawingSettings: Codable, Equatable { if let data = try? JSONEncoder().encode(self.tools) { try container.encode(data, forKey: "tools") } + if let data = try? JSONEncoder().encode(self.colors) { + try container.encode(data, forKey: "colors") + } } static func ==(lhs: DrawingSettings, rhs: DrawingSettings) -> Bool { - return lhs.tools == rhs.tools + return lhs.tools == rhs.tools && lhs.colors == rhs.colors } } @@ -734,7 +745,7 @@ private final class DrawingScreenComponent: CombinedComponent { let tools = self.drawingState.tools let _ = (self.context.sharedContext.accountManager.transaction { transaction -> Void in transaction.updateSharedData(ApplicationSpecificSharedDataKeys.drawingSettings, { _ in - return PreferencesEntry(DrawingSettings(tools: tools)) + return PreferencesEntry(DrawingSettings(tools: tools, colors: [])) }) }).start() } diff --git a/submodules/DrawingUI/Sources/DrawingTextEntity.swift b/submodules/DrawingUI/Sources/DrawingTextEntity.swift index baaddd7c01..21b63efde0 100644 --- a/submodules/DrawingUI/Sources/DrawingTextEntity.swift +++ b/submodules/DrawingUI/Sources/DrawingTextEntity.swift @@ -390,9 +390,11 @@ final class DrawingTextEntityView: DrawingEntityView, UITextViewDelegate { self.textView.becomeFirstResponder() UIView.animate(withDuration: 0.4, delay: 0.0, usingSpringWithDamping: 0.65, initialSpringVelocity: 0.0) { - self.transform = .identity - if let superview = self.superview { - self.center = CGPoint(x: superview.bounds.width / 2.0, y: superview.bounds.height / 2.0) + if let parentView = self.superview as? DrawingEntitiesView { + let scale = parentView.getEntityAdditionalScale() / (parentView.drawingView?.zoomScale ?? 1.0) + self.transform = CGAffineTransformMakeRotation(parentView.getEntityInitialRotation()).scaledBy(x: scale, y: scale) + + self.center = parentView.getEntityCenterPosition() } } diff --git a/submodules/DrawingUI/Sources/DrawingView.swift b/submodules/DrawingUI/Sources/DrawingView.swift index 69f0f6893d..142032d07c 100644 --- a/submodules/DrawingUI/Sources/DrawingView.swift +++ b/submodules/DrawingUI/Sources/DrawingView.swift @@ -555,7 +555,13 @@ public final class DrawingView: UIView, UIGestureRecognizerDelegate, UIPencilInt self.currentDrawingViewContainer.mask = nil self.currentDrawingViewContainer.image = nil } else { - currentDrawingRenderView.removeFromSuperview() + if let renderView = currentDrawingRenderView as? PenTool.RenderView, renderView.isDryingUp { + renderView.onDryingUp = { [weak renderView] in + renderView?.removeFromSuperview() + } + } else { + currentDrawingRenderView.removeFromSuperview() + } } self.currentDrawingRenderView = nil } @@ -651,10 +657,14 @@ public final class DrawingView: UIView, UIGestureRecognizerDelegate, UIPencilInt self.updateInternalState() } - if let uncommitedElement = self.uncommitedElement as? PenTool, uncommitedElement.hasArrow { - uncommitedElement.finishArrow({ + if let uncommitedElement = self.uncommitedElement as? PenTool { + if uncommitedElement.hasArrow { + uncommitedElement.finishArrow { + complete(true) + } + } else { complete(true) - }) + } } else { complete(synchronous) } diff --git a/submodules/DrawingUI/Sources/TextSettingsComponent.swift b/submodules/DrawingUI/Sources/TextSettingsComponent.swift index 59ffd9bf2e..efebcef577 100644 --- a/submodules/DrawingUI/Sources/TextSettingsComponent.swift +++ b/submodules/DrawingUI/Sources/TextSettingsComponent.swift @@ -231,9 +231,9 @@ final class TextFontComponent: Component { self.button.clipsToBounds = true self.button.setTitle(value.title, for: .normal) self.button.titleLabel?.font = value.uiFont(size: 13.0) - self.button.contentEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 26.0) + self.button.contentEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 20.0) var buttonSize = self.button.sizeThatFits(availableSize) - buttonSize.width += 39.0 - 13.0 + buttonSize.width += 20.0 buttonSize.height = 30.0 transition.setFrame(view: self.button, frame: CGRect(origin: .zero, size: buttonSize)) self.button.layer.cornerRadius = 11.0 diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoPaintStickersContext.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoPaintStickersContext.h index 17e3dbad06..61bfa2e36d 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoPaintStickersContext.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGPhotoPaintStickersContext.h @@ -53,6 +53,7 @@ @property (nonatomic, copy) CGPoint (^ _Nonnull getEntityCenterPosition)(void); @property (nonatomic, copy) CGFloat (^ _Nonnull getEntityInitialRotation)(void); +@property (nonatomic, copy) CGFloat (^ _Nonnull getEntityAdditionalScale)(void); @property (nonatomic, copy) void(^ _Nonnull hasSelectionChanged)(bool); @property (nonatomic, readonly) BOOL hasSelection; diff --git a/submodules/LegacyComponents/Sources/TGPhotoDrawingController.m b/submodules/LegacyComponents/Sources/TGPhotoDrawingController.m index a74d4d2316..1fb83c0727 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoDrawingController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoDrawingController.m @@ -246,6 +246,14 @@ const CGSize TGPhotoPaintingMaxSize = { 1920.0f, 1920.0f }; return [strongSelf entityInitialRotation]; }; + _entitiesView.getEntityAdditionalScale = ^CGFloat { + __strong TGPhotoDrawingController *strongSelf = weakSelf; + if (strongSelf == nil) + return 1.0f; + + return strongSelf->_photoEditor.cropRect.size.width / strongSelf->_photoEditor.originalSize.width; + }; + [self.view setNeedsLayout]; } diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index 911d9172f8..20d4968f6b 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -625,6 +625,15 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode case .action, .optionalAction: break case let .openContextMenu(tapMessage, selectAll, subFrame): + var tapMessage = tapMessage + if selectAll, case let .group(messages) = item.content, tapMessage.text.isEmpty { + for message in messages { + if !message.0.text.isEmpty { + tapMessage = message.0 + break + } + } + } item.controllerInteraction.openMessageContextMenu(tapMessage, selectAll, strongSelf, subFrame, gesture, nil) } }