Merge branch 'charlesmchen/imageEditorDesign4'

pull/2/head
Matthew Chen 6 years ago
commit 258a5beaaa

@ -617,6 +617,8 @@ extension AttachmentApprovalViewController: MediaMessageTextToolbarDelegate {
extension AttachmentApprovalViewController: AttachmentPrepViewControllerDelegate {
func prepViewController(_ prepViewController: AttachmentPrepViewController, didUpdateCaptionForAttachmentItem attachmentItem: SignalAttachmentItem) {
self.approvalDelegate?.attachmentApproval?(self, changedCaptionOfAttachment: attachmentItem.attachment)
updateMediaRail()
}
func prepViewControllerUpdateNavigationBar() {
@ -1636,6 +1638,16 @@ public class ApprovalRailCellView: GalleryRailCellView {
return button
}()
lazy var captionIndicator: UIView = {
let image = UIImage(named: "image_editor_caption")?.withRenderingMode(.alwaysTemplate)
let imageView = UIImageView(image: image)
imageView.tintColor = .white
imageView.layer.shadowColor = UIColor.black.cgColor
imageView.layer.shadowRadius = 2
imageView.layer.shadowOpacity = 0.66
return imageView
}()
override func setIsSelected(_ isSelected: Bool) {
super.setIsSelected(isSelected)
@ -1648,4 +1660,26 @@ public class ApprovalRailCellView: GalleryRailCellView {
deleteButton.removeFromSuperview()
}
}
override func configure(item: GalleryRailItem, delegate: GalleryRailCellViewDelegate) {
super.configure(item: item, delegate: delegate)
var hasCaption = false
if let attachmentItem = item as? SignalAttachmentItem {
if let captionText = attachmentItem.captionText {
hasCaption = captionText.count > 0
}
} else {
owsFailDebug("Invalid item.")
}
if hasCaption {
addSubview(captionIndicator)
captionIndicator.autoPinEdge(toSuperviewEdge: .top, withInset: 0)
captionIndicator.autoPinEdge(toSuperviewEdge: .leading, withInset: 4)
} else {
captionIndicator.removeFromSuperview()
}
}
}

@ -29,6 +29,11 @@ public class ImageEditorCanvasView: UIView {
private let itemIdsToIgnore: [String]
// We want strokes to be rendered above the image and behind text.
private static let brushLayerZ: CGFloat = +1
// We want text to be rendered above the image and strokes.
private static let textLayerZ: CGFloat = +2
@objc
public required init(model: ImageEditorModel,
itemIdsToIgnore: [String] = []) {
@ -53,7 +58,7 @@ public class ImageEditorCanvasView: UIView {
public let contentView = OWSLayerView()
// clipView is used to clip the content. It reflects the actual
// visible bounds of the content.
// visible bounds of the "canvas" content.
private let clipView = OWSLayerView()
private var contentViewConstraints = [NSLayoutConstraint]()
@ -461,6 +466,7 @@ public class ImageEditorCanvasView: UIView {
shapeLayer.fillColor = nil
shapeLayer.lineCap = kCALineCapRound
shapeLayer.lineJoin = kCALineJoinRound
shapeLayer.zPosition = brushLayerZ
return shapeLayer
}
@ -487,13 +493,15 @@ public class ImageEditorCanvasView: UIView {
// I don't think we need to enable allowsFontSubpixelQuantization
// or set truncationMode.
// This text needs to be rendered at a scale that reflects the sceen scaling
// AND the item's scaling.
layer.contentsScale = UIScreen.main.scale * item.scaling
// This text needs to be rendered at a scale that reflects:
//
// * The screen scaling (so that text looks sharp on Retina devices.
// * The item's scaling (so that text doesn't become blurry as you make it larger).
// * Model transform (so that text doesn't become blurry as you zoom the content).
layer.contentsScale = UIScreen.main.scale * item.scaling * transform.scaling
// TODO: Min with measured width.
let maxWidth = imageFrame.size.width * item.unitWidth
// let maxWidth = viewSize.width * item.unitWidth
let maxSize = CGSize(width: maxWidth, height: CGFloat.greatestFiniteMagnitude)
// TODO: Is there a more accurate way to measure text in a CATextLayer?
@ -520,6 +528,8 @@ public class ImageEditorCanvasView: UIView {
let transform = CGAffineTransform.identity.scaledBy(x: item.scaling, y: item.scaling).rotated(by: item.rotationRadians)
layer.setAffineTransform(transform)
layer.zPosition = textLayerZ
return layer
}

@ -101,10 +101,20 @@ public class ImageEditorTextItem: ImageEditorItem {
}
@objc
public class func empty(withColor color: ImageEditorColor, unitWidth: CGFloat, fontReferenceImageWidth: CGFloat) -> ImageEditorTextItem {
public class func empty(withColor color: ImageEditorColor,
unitWidth: CGFloat,
fontReferenceImageWidth: CGFloat,
scaling: CGFloat,
rotationRadians: 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)
return ImageEditorTextItem(text: "",
color: color,
font: font,
fontReferenceImageWidth: fontReferenceImageWidth,
unitWidth: unitWidth,
rotationRadians: rotationRadians,
scaling: scaling)
}
@objc
@ -148,6 +158,19 @@ public class ImageEditorTextItem: ImageEditorItem {
scaling: newScaling)
}
@objc
public func copy(withUnitCenter newUnitCenter: CGPoint, unitWidth newUnitWidth: CGFloat) -> ImageEditorTextItem {
return ImageEditorTextItem(itemId: itemId,
text: text,
color: color,
font: font,
fontReferenceImageWidth: fontReferenceImageWidth,
unitCenter: newUnitCenter,
unitWidth: newUnitWidth,
rotationRadians: rotationRadians,
scaling: scaling)
}
public override func outputScale() -> CGFloat {
return scaling
}

@ -104,6 +104,8 @@ public class ImageEditorTextViewController: OWSViewController, VAlignTextViewDel
private let textItem: ImageEditorTextItem
private let isNewItem: Bool
private let maxTextWidthPoints: CGFloat
private let textView = VAlignTextView(alignment: .center)
@ -117,10 +119,12 @@ public class ImageEditorTextViewController: OWSViewController, VAlignTextViewDel
init(delegate: ImageEditorTextViewControllerDelegate,
model: ImageEditorModel,
textItem: ImageEditorTextItem,
isNewItem: Bool,
maxTextWidthPoints: CGFloat) {
self.delegate = delegate
self.model = model
self.textItem = textItem
self.isNewItem = isNewItem
self.maxTextWidthPoints = maxTextWidthPoints
self.canvasView = ImageEditorCanvasView(model: model,
itemIdsToIgnore: [textItem.itemId])
@ -245,7 +249,33 @@ public class ImageEditorTextViewController: OWSViewController, VAlignTextViewDel
}
private func completeAndDismiss() {
self.delegate?.textEditDidComplete(textItem: textItem, text: textView.text, color: paletteView.selectedValue)
var newTextItem = textItem
if isNewItem {
let view = self.canvasView.gestureReferenceView
let viewBounds = view.bounds
// Ensure continuity of the new text item's location
// with its apparent location in this text editor.
let locationInView = view.convert(textView.bounds.center, from: textView)
let textCenterImageUnit = ImageEditorCanvasView.locationImageUnit(forLocationInView: locationInView,
viewBounds: viewBounds,
model: model,
transform: model.currentTransform())
// Same, but for size.
let imageFrame = ImageEditorCanvasView.imageFrame(forViewSize: viewBounds.size,
imageSize: model.srcImageSizePixels,
transform: model.currentTransform())
let unitWidth = textView.width() / imageFrame.width
newTextItem = textItem.copy(withUnitCenter: textCenterImageUnit, unitWidth: unitWidth)
}
// Hide the text view immediately to avoid animation glitches in the dismiss transition.
textView.isHidden = true
self.delegate?.textEditDidComplete(textItem: newTextItem, text: textView.text, color: paletteView.selectedValue)
self.dismiss(animated: false) {
// Do nothing.

@ -146,11 +146,19 @@ public class ImageEditorView: UIView {
let textWidthPoints = viewSize.width * ImageEditorTextItem.kDefaultUnitWidth
let textWidthUnit = textWidthPoints / imageFrame.size.width
// New items should be aligned "upright", so they should have the _opposite_
// of the current transform rotation.
let rotationRadians = -model.currentTransform().rotationRadians
// Similarly, the size of the text item shuo
let scaling = 1 / model.currentTransform().scaling
let textItem = ImageEditorTextItem.empty(withColor: currentColor,
unitWidth: textWidthUnit,
fontReferenceImageWidth: imageFrame.size.width)
fontReferenceImageWidth: imageFrame.size.width,
scaling: scaling,
rotationRadians: rotationRadians)
edit(textItem: textItem)
edit(textItem: textItem, isNewItem: true)
}
@objc func didTapDone(sender: UIButton) {
@ -178,7 +186,7 @@ public class ImageEditorView: UIView {
return
}
edit(textItem: textItem)
edit(textItem: textItem, isNewItem: false)
}
// MARK: - Pinch Gesture
@ -408,7 +416,7 @@ public class ImageEditorView: UIView {
// MARK: - Edit Text Tool
private func edit(textItem: ImageEditorTextItem) {
private func edit(textItem: ImageEditorTextItem, isNewItem: Bool) {
Logger.verbose("")
// TODO:
@ -418,6 +426,7 @@ public class ImageEditorView: UIView {
let textEditor = ImageEditorTextViewController(delegate: self,
model: model,
textItem: textItem,
isNewItem: isNewItem,
maxTextWidthPoints: maxTextWidthPoints)
self.delegate?.imageEditor(presentFullScreenView: textEditor,
isTransparent: false)

@ -202,6 +202,10 @@ public extension CGPoint {
y: Swift.max(y, value.y))
}
public var length: CGFloat {
return sqrt(x * x + y * y)
}
public static let unit: CGPoint = CGPoint(x: 1.0, y: 1.0)
public static let unitMidpoint: CGPoint = CGPoint(x: 0.5, y: 0.5)

Loading…
Cancel
Save