From b64be3aa73f872338fefb7146696273c677fef28 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 28 Feb 2019 14:23:11 -0500 Subject: [PATCH] Clean up image editor. --- .../ImageEditorBrushViewController.swift | 27 +-- .../ImageEditor/ImageEditorPaletteView.swift | 94 ++++++---- .../ImageEditor/ImageEditorTextItem.swift | 12 +- .../ImageEditorTextViewController.swift | 106 +++++++++--- .../Views/ImageEditor/ImageEditorView.swift | 160 ++---------------- SignalMessaging/categories/UIView+OWS.swift | 2 +- 6 files changed, 172 insertions(+), 229 deletions(-) diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift b/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift index ffcc24fe3..e759ce00b 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift @@ -4,16 +4,6 @@ import UIKit -//@objc -//public protocol ImageEditorViewDelegate: class { -// func imageEditor(presentFullScreenOverlay viewController: UIViewController, -// withNavigation: Bool) -// func imageEditorPresentCaptionView() -// func imageEditorUpdateNavigationBar() -//} - -// MARK: - - @objc public protocol ImageEditorBrushViewControllerDelegate: class { func brushDidComplete() @@ -30,15 +20,17 @@ public class ImageEditorBrushViewController: OWSViewController { private let canvasView: ImageEditorCanvasView - private let paletteView = ImageEditorPaletteView() + private let paletteView: ImageEditorPaletteView private var brushGestureRecognizer: ImageEditorPanGestureRecognizer? init(delegate: ImageEditorBrushViewControllerDelegate, - model: ImageEditorModel) { + model: ImageEditorModel, + currentColor: ImageEditorColor) { self.delegate = delegate self.model = model self.canvasView = ImageEditorCanvasView(model: model) + self.paletteView = ImageEditorPaletteView(currentColor: currentColor) super.init(nibName: nil, bundle: nil) @@ -55,6 +47,7 @@ public class ImageEditorBrushViewController: OWSViewController { public override func loadView() { self.view = UIView() self.view.backgroundColor = .black + self.view.isOpaque = true canvasView.configureSubviews() self.view.addSubview(canvasView) @@ -63,7 +56,7 @@ public class ImageEditorBrushViewController: OWSViewController { paletteView.delegate = self self.view.addSubview(paletteView) paletteView.autoVCenterInSuperview() - paletteView.autoPinEdge(toSuperviewEdge: .leading, withInset: 20) + paletteView.autoPinEdge(toSuperviewEdge: .trailing, withInset: 20) self.view.isUserInteractionEnabled = true @@ -103,12 +96,6 @@ public class ImageEditorBrushViewController: OWSViewController { updateNavigationBar(navigationBarItems: navigationBarItems) } - private var currentColor: UIColor { - get { - return paletteView.selectedColor - } - } - // MARK: - Actions @objc func didTapUndo(sender: UIButton) { @@ -168,7 +155,7 @@ public class ImageEditorBrushViewController: OWSViewController { self.currentStrokeSamples.append(newSample) } - let strokeColor = currentColor + let strokeColor = paletteView.selectedValue.color // TODO: Tune stroke width. let unitStrokeWidth = ImageEditorStrokeItem.defaultUnitStrokeWidth() diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorPaletteView.swift b/SignalMessaging/Views/ImageEditor/ImageEditorPaletteView.swift index 6153b842b..68363fcd5 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorPaletteView.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorPaletteView.swift @@ -10,11 +10,60 @@ public protocol ImageEditorPaletteViewDelegate: class { // MARK: - +@objc +public class ImageEditorColor: NSObject { + public let color: UIColor + + // Colors are chosen from a spectrum of colors. + // This unit value represents the location of the + // color within that spectrum. + public let palettePhase: CGFloat + + public var cgColor: CGColor { + return color.cgColor + } + + public required init(color: UIColor, palettePhase: CGFloat) { + self.color = color + self.palettePhase = palettePhase + } + + public class func defaultColor() -> ImageEditorColor { + return ImageEditorColor(color: UIColor(rgbHex: 0xffffff), palettePhase: 0) + } + + public static var gradientUIColors: [UIColor] { + return [ + UIColor(rgbHex: 0xffffff), + UIColor(rgbHex: 0xff0000), + UIColor(rgbHex: 0xff00ff), + UIColor(rgbHex: 0x0000ff), + UIColor(rgbHex: 0x00ffff), + UIColor(rgbHex: 0x00ff00), + UIColor(rgbHex: 0xffff00), + UIColor(rgbHex: 0xff5500), + UIColor(rgbHex: 0x000000) + ] + } + + public static var gradientCGColors: [CGColor] { + return gradientUIColors.map({ (color) in + return color.cgColor + }) + } +} + +// MARK: - + public class ImageEditorPaletteView: UIView { public weak var delegate: ImageEditorPaletteViewDelegate? - public required init() { + public var selectedValue: ImageEditorColor + + public required init(currentColor: ImageEditorColor) { + self.selectedValue = currentColor + super.init(frame: .zero) createContents() @@ -27,9 +76,6 @@ public class ImageEditorPaletteView: UIView { // MARK: - Views - // The actual default is selected later. - public var selectedColor = UIColor.white - private let imageView = UIImageView() private let selectionView = UIView() private let selectionWrapper = OWSLayerView() @@ -84,36 +130,36 @@ public class ImageEditorPaletteView: UIView { // 0 = the color at the top of the image is selected. // 1 = the color at the bottom of the image is selected. private let selectionSize: CGFloat = 20 - private var selectionAlpha: CGFloat = 0 private func selectColor(atLocationY y: CGFloat) { - selectionAlpha = y.inverseLerp(0, imageView.height(), shouldClamp: true) + let palettePhase = y.inverseLerp(0, imageView.height(), shouldClamp: true) + self.selectedValue = value(for: palettePhase) updateState() delegate?.selectedColorDidChange() } - private func updateState() { - var selectedColor = UIColor.white - if let image = imageView.image { - if let imageColor = image.color(atLocation: CGPoint(x: CGFloat(image.size.width) * 0.5, y: CGFloat(image.size.height) * selectionAlpha)) { - selectedColor = imageColor - } else { - owsFailDebug("Couldn't determine image color.") - } - } else { + private func value(for palettePhase: CGFloat) -> ImageEditorColor { + guard let image = imageView.image else { owsFailDebug("Missing image.") + return ImageEditorColor.defaultColor() + } + guard let color = image.color(atLocation: CGPoint(x: CGFloat(image.size.width) * 0.5, y: CGFloat(image.size.height) * palettePhase)) else { + owsFailDebug("Missing color.") + return ImageEditorColor.defaultColor() } - self.selectedColor = selectedColor + return ImageEditorColor(color: color, palettePhase: palettePhase) + } - selectionView.backgroundColor = selectedColor + private func updateState() { + selectionView.backgroundColor = selectedValue.color guard let selectionConstraint = selectionConstraint else { owsFailDebug("Missing selectionConstraint.") return } - let selectionY = selectionWrapper.height() * selectionAlpha + let selectionY = selectionWrapper.height() * selectedValue.palettePhase selectionConstraint.constant = selectionY } @@ -142,17 +188,7 @@ public class ImageEditorPaletteView: UIView { gradientView.layer.addSublayer(gradientLayer) gradientLayer.frame = gradientBounds // See: https://github.com/signalapp/Signal-Android/blob/master/res/values/arrays.xml#L267 - gradientLayer.colors = [ - UIColor(rgbHex: 0xffffff).cgColor, - UIColor(rgbHex: 0xff0000).cgColor, - UIColor(rgbHex: 0xff00ff).cgColor, - UIColor(rgbHex: 0x0000ff).cgColor, - UIColor(rgbHex: 0x00ffff).cgColor, - UIColor(rgbHex: 0x00ff00).cgColor, - UIColor(rgbHex: 0xffff00).cgColor, - UIColor(rgbHex: 0xff5500).cgColor, - UIColor(rgbHex: 0x000000).cgColor - ] + gradientLayer.colors = ImageEditorColor.gradientCGColors gradientLayer.startPoint = CGPoint.zero gradientLayer.endPoint = CGPoint(x: 0, y: gradientSize.height) gradientLayer.endPoint = CGPoint(x: 0, y: 1.0) diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorTextItem.swift b/SignalMessaging/Views/ImageEditor/ImageEditorTextItem.swift index 5c0b84828..1056c2bcb 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorTextItem.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorTextItem.swift @@ -11,7 +11,7 @@ public class ImageEditorTextItem: ImageEditorItem { public let text: String @objc - public let color: UIColor + public let color: ImageEditorColor @objc public let font: UIFont @@ -60,7 +60,7 @@ public class ImageEditorTextItem: ImageEditorItem { @objc public init(text: String, - color: UIColor, + color: ImageEditorColor, font: UIFont, fontReferenceImageWidth: CGFloat, unitCenter: ImageEditorSample = ImageEditorSample(x: 0.5, y: 0.5), @@ -81,7 +81,7 @@ public class ImageEditorTextItem: ImageEditorItem { private init(itemId: String, text: String, - color: UIColor, + color: ImageEditorColor, font: UIFont, fontReferenceImageWidth: CGFloat, unitCenter: ImageEditorSample, @@ -101,17 +101,17 @@ public class ImageEditorTextItem: ImageEditorItem { } @objc - public class func empty(withColor color: UIColor, unitWidth: CGFloat, fontReferenceImageWidth: CGFloat) -> ImageEditorTextItem { + public class func empty(withColor color: ImageEditorColor, unitWidth: CGFloat, fontReferenceImageWidth: CGFloat) -> ImageEditorTextItem { // TODO: Tune the default font size. let font = UIFont.boldSystemFont(ofSize: 30.0) return ImageEditorTextItem(text: "", color: color, font: font, fontReferenceImageWidth: fontReferenceImageWidth, unitWidth: unitWidth) } @objc - public func copy(withText newText: String) -> ImageEditorTextItem { + public func copy(withText newText: String, color newColor: ImageEditorColor) -> ImageEditorTextItem { return ImageEditorTextItem(itemId: itemId, text: newText, - color: color, + color: newColor, font: font, fontReferenceImageWidth: fontReferenceImageWidth, unitCenter: unitCenter, diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorTextViewController.swift b/SignalMessaging/Views/ImageEditor/ImageEditorTextViewController.swift index a54613579..0b6be3c4d 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorTextViewController.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorTextViewController.swift @@ -92,7 +92,7 @@ private class VAlignTextView: UITextView { @objc public protocol ImageEditorTextViewControllerDelegate: class { - func textEditDidComplete(textItem: ImageEditorTextItem, text: String?) + func textEditDidComplete(textItem: ImageEditorTextItem, text: String?, color: ImageEditorColor) func textEditDidCancel() } @@ -106,14 +106,24 @@ public class ImageEditorTextViewController: OWSViewController, VAlignTextViewDel private let maxTextWidthPoints: CGFloat - private let textView = VAlignTextView(alignment: .bottom) + private let textView = VAlignTextView(alignment: .center) + + private let model: ImageEditorModel + + private let canvasView: ImageEditorCanvasView + + private let paletteView: ImageEditorPaletteView init(delegate: ImageEditorTextViewControllerDelegate, + model: ImageEditorModel, textItem: ImageEditorTextItem, maxTextWidthPoints: CGFloat) { self.delegate = delegate + self.model = model self.textItem = textItem self.maxTextWidthPoints = maxTextWidthPoints + self.canvasView = ImageEditorCanvasView(model: model) + self.paletteView = ImageEditorPaletteView(currentColor: textItem.color) super.init(nibName: nil, bundle: nil) @@ -131,43 +141,63 @@ public class ImageEditorTextViewController: OWSViewController, VAlignTextViewDel super.viewWillAppear(animated) textView.becomeFirstResponder() + + self.view.layoutSubviews() } public override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) textView.becomeFirstResponder() + + self.view.layoutSubviews() } public override func loadView() { self.view = UIView() - self.view.backgroundColor = UIColor(white: 0.5, alpha: 0.5) + self.view.backgroundColor = .black + self.view.isOpaque = true + + canvasView.configureSubviews() + self.view.addSubview(canvasView) + canvasView.autoPinEdgesToSuperviewEdges() + + let tintView = UIView() + tintView.backgroundColor = UIColor(white: 0, alpha: 0.33) + tintView.isOpaque = false + self.view.addSubview(tintView) + tintView.autoPinEdgesToSuperviewEdges() + tintView.layer.opacity = 0 + UIView.animate(withDuration: 0.25, animations: { + tintView.layer.opacity = 1 + }, completion: { (_) in + tintView.layer.opacity = 1 + }) configureTextView() - navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .stop, - target: self, - action: #selector(didTapBackButton)) - self.view.layoutMargins = UIEdgeInsets(top: 16, left: 20, bottom: 16, right: 20) + self.view.addSubview(textView) textView.autoPinTopToSuperviewMargin() textView.autoHCenterInSuperview() - // In order to have text wrapping be as WYSIWYG as possible, we limit the text view - // to the max text width on the image. -// let maxTextWidthPoints = max(textItem.widthPoints, 200) -// textView.autoSetDimension(.width, toSize: maxTextWidthPoints, relation: .lessThanOrEqual) -// textView.autoPinEdge(toSuperviewMargin: .leading, relation: .greaterThanOrEqual) -// textView.autoPinEdge(toSuperviewMargin: .trailing, relation: .greaterThanOrEqual) - textView.autoPinEdge(toSuperviewMargin: .leading) - textView.autoPinEdge(toSuperviewMargin: .trailing) self.autoPinView(toBottomOfViewControllerOrKeyboard: textView, avoidNotch: true) + + // TODO: Honor old color state. + paletteView.delegate = self + self.view.addSubview(paletteView) + paletteView.autoVCenterInSuperview() + paletteView.autoPinEdge(toSuperviewEdge: .trailing, withInset: 20) + // This will determine the text view's size. + paletteView.autoPinEdge(.leading, to: .trailing, of: textView, withOffset: 8) + + updateNavigationBar() } private func configureTextView() { textView.text = textItem.text textView.font = textItem.font - textView.textColor = textItem.color + textView.textColor = textItem.color.color textView.isEditable = true textView.backgroundColor = .clear @@ -186,23 +216,37 @@ public class ImageEditorTextViewController: OWSViewController, VAlignTextViewDel textView.contentInset = .zero } - // MARK: - Events + private func updateNavigationBar() { + let undoButton = navigationBarButton(imageName: "image_editor_undo", + selector: #selector(didTapUndo(sender:))) + let doneButton = navigationBarButton(imageName: "image_editor_checkmark_full", + selector: #selector(didTapDone(sender:))) - @objc public func didTapBackButton() { - completeAndDismiss() + let navigationBarItems = [undoButton, doneButton] + updateNavigationBar(navigationBarItems: navigationBarItems) } - private func completeAndDismiss() { + // MARK: - Events + + @objc func didTapUndo(sender: UIButton) { + Logger.verbose("") - // Before we take a screenshot, make sure selection state - // auto-complete suggestions, cursor don't affect screenshot. - textView.resignFirstResponder() - if textView.isFirstResponder { - owsFailDebug("Text view is still first responder.") + // TODO: Honor color state. + self.delegate?.textEditDidCancel() + + self.dismiss(animated: false) { + // Do nothing. } - textView.selectedTextRange = nil + } - self.delegate?.textEditDidComplete(textItem: textItem, text: textView.text) + @objc func didTapDone(sender: UIButton) { + Logger.verbose("") + + completeAndDismiss() + } + + private func completeAndDismiss() { + self.delegate?.textEditDidComplete(textItem: textItem, text: textView.text, color: paletteView.selectedValue) self.dismiss(animated: false) { // Do nothing. @@ -215,3 +259,11 @@ public class ImageEditorTextViewController: OWSViewController, VAlignTextViewDel completeAndDismiss() } } + +// MARK: - + +extension ImageEditorTextViewController: ImageEditorPaletteViewDelegate { + public func selectedColorDidChange() { + self.textView.textColor = self.paletteView.selectedValue.color + } +} diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorView.swift b/SignalMessaging/Views/ImageEditor/ImageEditorView.swift index b65483340..24cb50d02 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorView.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorView.swift @@ -25,30 +25,8 @@ public class ImageEditorView: UIView { private let canvasView: ImageEditorCanvasView - private let paletteView = ImageEditorPaletteView() - - enum EditorMode: String { - // This is the default mode. It is used for interacting with text items. - case none - case brush - case text - } - - private var editorMode = EditorMode.none { - didSet { - AssertIsOnMainThread() - - updateButtons() - updateGestureState() - delegate?.imageEditorUpdateNavigationBar() - } - } - - private var currentColor: UIColor { - get { - return paletteView.selectedColor - } - } + // TODO: We could hang this on the model or make this static. + private var currentColor = ImageEditorColor.defaultColor() @objc public required init(model: ImageEditorModel, delegate: ImageEditorViewDelegate) { @@ -78,8 +56,6 @@ public class ImageEditorView: UIView { self.addSubview(canvasView) canvasView.autoPinEdgesToSuperviewEdges() - paletteView.delegate = self - self.isUserInteractionEnabled = true let moveTextGestureRecognizer = ImageEditorPanGestureRecognizer(target: self, action: #selector(handleMoveTextGesture(_:))) @@ -102,60 +78,16 @@ public class ImageEditorView: UIView { // editorGestureRecognizer.require(toFail: tapGestureRecognizer) // editorGestureRecognizer.require(toFail: pinchGestureRecognizer) - updateGestureState() - return true } - private func commitTextEditingChanges(textItem: ImageEditorTextItem, textView: UITextView) { - AssertIsOnMainThread() - - guard let text = textView.text?.ows_stripped(), - text.count > 0 else { - model.remove(item: textItem) - return - } - - // Model items are immutable; we _replace_ the item rather than modify it. - let newItem = textItem.copy(withText: text) - if model.has(itemForId: textItem.itemId) { - model.replace(item: newItem, suppressUndo: false) - } else { - model.append(item: newItem) - } - } - // TODO: Should this method be private? @objc public func addControls(to containerView: UIView, viewController: UIViewController) { - - containerView.addSubview(paletteView) - paletteView.autoVCenterInSuperview() - paletteView.autoPinLeadingToSuperviewMargin(withInset: 10) - - updateButtons() - delegate?.imageEditorUpdateNavigationBar() } - private func updateButtons() { - var hasPalette = false - switch editorMode { - case .text: - // TODO: - hasPalette = true - break - case .brush: - hasPalette = true - case .none: - hasPalette = false - break - } - - paletteView.isHidden = !hasPalette - } - // MARK: - Navigation Bar public func navigationBarItems() -> [UIView] { @@ -170,17 +102,10 @@ public class ImageEditorView: UIView { let captionButton = navigationBarButton(imageName: "image_editor_caption", selector: #selector(didTapCaption(sender:))) - switch editorMode { - case .text: - return [] - case .brush: - return [] - case .none: - if model.canUndo() { - return [undoButton, newTextButton, brushButton, cropButton, captionButton] - } else { - return [newTextButton, brushButton, cropButton, captionButton] - } + if model.canUndo() { + return [undoButton, newTextButton, brushButton, cropButton, captionButton] + } else { + return [newTextButton, brushButton, cropButton, captionButton] } } @@ -198,9 +123,7 @@ public class ImageEditorView: UIView { @objc func didTapBrush(sender: UIButton) { Logger.verbose("") - self.editorMode = .brush - - let brushView = ImageEditorBrushViewController(delegate: self, model: model) + let brushView = ImageEditorBrushViewController(delegate: self, model: model, currentColor: currentColor) self.delegate?.imageEditor(presentFullScreenOverlay: brushView, withNavigation: true) } @@ -233,44 +156,10 @@ public class ImageEditorView: UIView { Logger.verbose("") delegate?.imageEditorPresentCaptionView() - -// // TODO: -// let maxTextWidthPoints = model.srcImageSizePixels.width * ImageEditorTextItem.kDefaultUnitWidth -// // let maxTextWidthPoints = canvasView.imageView.width() * ImageEditorTextItem.kDefaultUnitWidth -// -// let textEditor = ImageEditorTextViewController(delegate: self, textItem: textItem, maxTextWidthPoints: maxTextWidthPoints) -// self.delegate?.imageEditor(presentFullScreenOverlay: textEditor, -// withNavigation: true) - - // TODO: } @objc func didTapDone(sender: UIButton) { Logger.verbose("") - - self.editorMode = .none - } - - // MARK: - Gestures - - private func updateGestureState() { - AssertIsOnMainThread() - - switch editorMode { - case .none: - moveTextGestureRecognizer?.isEnabled = true - tapGestureRecognizer?.isEnabled = true - pinchGestureRecognizer?.isEnabled = true - case .brush: - // Brush strokes can start and end (and return from) outside the view. - moveTextGestureRecognizer?.isEnabled = false - tapGestureRecognizer?.isEnabled = false - pinchGestureRecognizer?.isEnabled = false - case .text: - moveTextGestureRecognizer?.isEnabled = false - tapGestureRecognizer?.isEnabled = false - pinchGestureRecognizer?.isEnabled = false - } } // MARK: - Tap Gesture @@ -483,7 +372,7 @@ public class ImageEditorView: UIView { self.currentStrokeSamples.append(newSample) } - let strokeColor = currentColor + let strokeColor = currentColor.color // TODO: Tune stroke width. let unitStrokeWidth = ImageEditorStrokeItem.defaultUnitStrokeWidth() @@ -527,13 +416,14 @@ public class ImageEditorView: UIView { private func edit(textItem: ImageEditorTextItem) { Logger.verbose("") - self.editorMode = .text - // TODO: let maxTextWidthPoints = model.srcImageSizePixels.width * ImageEditorTextItem.kDefaultUnitWidth // let maxTextWidthPoints = canvasView.imageView.width() * ImageEditorTextItem.kDefaultUnitWidth - let textEditor = ImageEditorTextViewController(delegate: self, textItem: textItem, maxTextWidthPoints: maxTextWidthPoints) + let textEditor = ImageEditorTextViewController(delegate: self, + model: model, + textItem: textItem, + maxTextWidthPoints: maxTextWidthPoints) self.delegate?.imageEditor(presentFullScreenOverlay: textEditor, withNavigation: true) } @@ -543,8 +433,6 @@ public class ImageEditorView: UIView { private func presentCropTool() { Logger.verbose("") - self.editorMode = .none - guard let srcImage = canvasView.loadSrcImage() else { owsFailDebug("Couldn't load src image.") return @@ -573,10 +461,6 @@ extension ImageEditorView: UIGestureRecognizerDelegate { owsFailDebug("Unexpected gesture.") return false } - guard editorMode == .none else { - // We only filter touches when in default mode. - return true - } let location = touch.location(in: canvasView.gestureReferenceView) let isInTextArea = self.textLayer(forLocation: location) != nil @@ -590,14 +474,10 @@ extension ImageEditorView: ImageEditorModelObserver { public func imageEditorModelDidChange(before: ImageEditorContents, after: ImageEditorContents) { - updateButtons() - delegate?.imageEditorUpdateNavigationBar() } public func imageEditorModelDidChange(changedItemIds: [String]) { - updateButtons() - delegate?.imageEditorUpdateNavigationBar() } } @@ -606,11 +486,9 @@ extension ImageEditorView: ImageEditorModelObserver { extension ImageEditorView: ImageEditorTextViewControllerDelegate { - public func textEditDidComplete(textItem: ImageEditorTextItem, text: String?) { + public func textEditDidComplete(textItem: ImageEditorTextItem, text: String?, color: ImageEditorColor) { AssertIsOnMainThread() - self.editorMode = .none - guard let text = text?.ows_stripped(), text.count > 0 else { if model.has(itemForId: textItem.itemId) { @@ -620,7 +498,7 @@ extension ImageEditorView: ImageEditorTextViewControllerDelegate { } // Model items are immutable; we _replace_ the item rather than modify it. - let newItem = textItem.copy(withText: text) + let newItem = textItem.copy(withText: text, color: color) if model.has(itemForId: textItem.itemId) { model.replace(item: newItem, suppressUndo: false) } else { @@ -629,7 +507,6 @@ extension ImageEditorView: ImageEditorTextViewControllerDelegate { } public func textEditDidCancel() { - self.editorMode = .none } } @@ -648,16 +525,7 @@ extension ImageEditorView: ImageEditorCropViewControllerDelegate { // MARK: - -extension ImageEditorView: ImageEditorPaletteViewDelegate { - public func selectedColorDidChange() { - // TODO: - } -} - -// MARK: - - extension ImageEditorView: ImageEditorBrushViewControllerDelegate { public func brushDidComplete() { - self.editorMode = .none } } diff --git a/SignalMessaging/categories/UIView+OWS.swift b/SignalMessaging/categories/UIView+OWS.swift index 789f6b056..c50db8c35 100644 --- a/SignalMessaging/categories/UIView+OWS.swift +++ b/SignalMessaging/categories/UIView+OWS.swift @@ -129,7 +129,7 @@ public extension CGFloat { return CGFloatClamp(self, minValue, maxValue) } - public func clamp01(_ minValue: CGFloat, _ maxValue: CGFloat) -> CGFloat { + public func clamp01() -> CGFloat { return CGFloatClamp01(self) }