From 2f7880af8e70163f9a3aafe0a1d588178eccefda Mon Sep 17 00:00:00 2001 From: Matthew Chen <matthew@signal.org> Date: Tue, 12 Mar 2019 13:17:49 -0400 Subject: [PATCH 1/7] Fix hit testing of text layers. --- .../Views/ImageEditor/ImageEditorCanvasView.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorCanvasView.swift b/SignalMessaging/Views/ImageEditor/ImageEditorCanvasView.swift index dbe3448a3..dba18ef70 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorCanvasView.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorCanvasView.swift @@ -642,10 +642,24 @@ public class ImageEditorCanvasView: UIView { guard let sublayers = contentView.layer.sublayers else { return nil } + + // First we build a map of all text layers. + var layerMap = [String: EditorTextLayer]() for layer in sublayers { guard let textLayer = layer as? EditorTextLayer else { continue } + layerMap[textLayer.itemId] = textLayer + } + + // The layer ordering in the model is authoritative. + // Iterate over the layers in _reverse_ order of which they appear + // in the model, so that layers "on top" are hit first. + for item in model.items().reversed() { + guard let textLayer = layerMap[item.itemId] else { + // Not a text layer. + continue + } if textLayer.hitTest(point) != nil { return textLayer } From 66efcb4639b75440cf84ca5d4994db232f8f4355 Mon Sep 17 00:00:00 2001 From: Matthew Chen <matthew@signal.org> Date: Tue, 12 Mar 2019 13:27:35 -0400 Subject: [PATCH 2/7] Update rail icons. --- .../x-24.imageset/Contents.json | 23 ++++++++++++++++++ .../Images.xcassets/x-24.imageset/x-24@1x.png | Bin 0 -> 243 bytes .../Images.xcassets/x-24.imageset/x-24@2x.png | Bin 0 -> 398 bytes .../Images.xcassets/x-24.imageset/x-24@3x.png | Bin 0 -> 573 bytes .../AttachmentApprovalViewController.swift | 22 +++++++++-------- SignalMessaging/Views/GalleryRailView.swift | 9 ++++--- 6 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 Signal/Images.xcassets/x-24.imageset/Contents.json create mode 100644 Signal/Images.xcassets/x-24.imageset/x-24@1x.png create mode 100644 Signal/Images.xcassets/x-24.imageset/x-24@2x.png create mode 100644 Signal/Images.xcassets/x-24.imageset/x-24@3x.png diff --git a/Signal/Images.xcassets/x-24.imageset/Contents.json b/Signal/Images.xcassets/x-24.imageset/Contents.json new file mode 100644 index 000000000..1f25af162 --- /dev/null +++ b/Signal/Images.xcassets/x-24.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "x-24@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "x-24@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "x-24@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Signal/Images.xcassets/x-24.imageset/x-24@1x.png b/Signal/Images.xcassets/x-24.imageset/x-24@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..ee6d0b887443c3733f4bf3dc008a1adce365639a GIT binary patch literal 243 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GGLLkg|>2BR0px{zZ z7sn8f&bOhtTn!35wXa#^ZYq~4CkHIZJIgEcH&fxt=UR_fi>^r-z4j>muhP(=B`A6@ zMkG5zJ7N#}d4>Zlbry_M>dr}>*=zbIi2c0g0`*-^VY4<UoDx;qeqpBoV+GF|%ZG~_ zr%i0jj0!*C?eRt+V}U}i;=*Jdy<6Wd1@&Hi|JSAK=RV(UJs@>WGsShchAuJR{iW<~ m>yER_Cs;lH?|)y9K|JM*R^O4Q$E1M{X7F_Nb6Mw<&;$VBSYMt1 literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/x-24.imageset/x-24@2x.png b/Signal/Images.xcassets/x-24.imageset/x-24@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ea502285caf8531820a4cffebcb866af3b2bc408 GIT binary patch literal 398 zcmV;90df9`P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00009a7bBm000&x z000&x0ZCFM@Bjb-KuJVFRA_<iS-}m1Fbs4$0V6Rgqc8&9q#LA)WcsKbHv%8QYEJU! z0ADUZ;v^~OOp);j-TGnR1{el<qsc%@X%ZwDt(rd#q?8sSTCX(0S}SYYDDyxqh^QpU z92*f$wR^pyXt36<yI8pe@wp%q!A%^|6hto*N3{eYZn(h284W>bfi!V8w;*bPFyWC? z5LS4a@X95KOM1<-BQz4(0Pjyx5J(e{|41VdCQu`pAP^>?!>~qrny{|9Xltai361lc z#Wm8|1hkG41kePe2n@fZ6psG(6RI>m#!qZC{{F*g=!q<JDG|Du3tdi!UeJVIQifjC zhu&5Ry|EQ~Yca~^Znd1wIluVf9Zw>fnTLRL&#bj$Gc`3=U%j$ibvB^93G-~AMAJcc sIWaMN0f1J`aZ=wK!$5Bg16@HxZ<K!I{@13q=l}o!07*qoM6N<$f@d?Gl>h($ literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/x-24.imageset/x-24@3x.png b/Signal/Images.xcassets/x-24.imageset/x-24@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..cbb9bb263d56a3b51b69b48ace2bb48ad7eb0b3a GIT binary patch literal 573 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!oCO|{#S9FJ<{->y95KI&fr0V8 zr;B4q#hkZu8aodg2(X05J6in|3!3Hasj2z!^2zcA?g#mgso%Y+c4=;c__PV4ZqF49 zRlNO9SvF_AUVYPPud72F#|Z&ONhJkmmXwYL9>EEUOhzS~0bZG&ns;5C1ExlKpPjx+ zJGj@F?Sn=;;}6CH>*_xl)1|IQot}OC<>$4ny7>>DNGiO2@I-rp%LSu`)a!v69=sO+ z<FbxliQ&yQv*KZWIeBZB!)KlecCm{&(%P;pHWNI<wKCjSX@+3X`6w3y=_U6}I}+49 zlz)jG)S2M+RkKM_f%oldF*m)MFUvz&Ci)+Ex;lni+3C|SLjgw@k9GT}Y&8&4dB1TQ zhms?gp}^W!K?T>Dr#cjvmIQp>6ZL{q^VZy^hrgSzU7eubkbjY5&$a7ew{4&Q(T=h@ zmC8JoaiyBL#fK=182>N(ejdpvYGyt^^=k8kn1>DC=eONqkln*Kb=&giM%%d;Ocu`! z_c+WbSrFHoJxPAatp^><uI&>|mP>V6MuwibE!$Oj*vBw`r`9vy>Z38=0?)KMAC0LB zJ9C!1Yv*5AL-PR5XJR%-?;Ke<<936nd)sC1NgPr082$J?lrm=WZ<cvIrQdmOgNT$L zbI^VES7vkdj1Sy&wEDC4)~x^kk~+N4V~G_Phgl4N7^5wi+4&uECjrv~gQu&X%Q~lo FCIH1j>9_y@ literal 0 HcmV?d00001 diff --git a/SignalMessaging/ViewControllers/AttachmentApprovalViewController.swift b/SignalMessaging/ViewControllers/AttachmentApprovalViewController.swift index 40e681eda..a442a68aa 100644 --- a/SignalMessaging/ViewControllers/AttachmentApprovalViewController.swift +++ b/SignalMessaging/ViewControllers/AttachmentApprovalViewController.swift @@ -1676,12 +1676,14 @@ public class ApprovalRailCellView: GalleryRailCellView { strongSelf.approvalRailCellDelegate?.approvalRailCellView(strongSelf, didRemoveItem: attachmentItem) } - button.setImage(#imageLiteral(resourceName: "ic_circled_x"), for: .normal) - - let kInsetDistance: CGFloat = 5 - button.imageEdgeInsets = UIEdgeInsets(top: kInsetDistance, left: kInsetDistance, bottom: kInsetDistance, right: kInsetDistance) - - let kButtonWidth: CGFloat = 24 + kInsetDistance * 2 + button.setImage(UIImage(named: "x-24")?.withRenderingMode(.alwaysTemplate), for: .normal) + button.tintColor = .white + button.layer.shadowColor = UIColor.black.cgColor + button.layer.shadowRadius = 2 + button.layer.shadowOpacity = 0.66 + button.layer.shadowOffset = .zero + + let kButtonWidth: CGFloat = 24 button.autoSetDimensions(to: CGSize(width: kButtonWidth, height: kButtonWidth)) return button @@ -1704,8 +1706,8 @@ public class ApprovalRailCellView: GalleryRailCellView { if isSelected { addSubview(deleteButton) - deleteButton.autoPinEdge(toSuperviewEdge: .top, withInset: -12) - deleteButton.autoPinEdge(toSuperviewEdge: .trailing, withInset: -8) + deleteButton.autoPinEdge(toSuperviewEdge: .top, withInset: cellBorderWidth) + deleteButton.autoPinEdge(toSuperviewEdge: .trailing, withInset: cellBorderWidth + 4) } else { deleteButton.removeFromSuperview() } @@ -1726,8 +1728,8 @@ public class ApprovalRailCellView: GalleryRailCellView { if hasCaption { addSubview(captionIndicator) - captionIndicator.autoPinEdge(toSuperviewEdge: .top, withInset: 2) - captionIndicator.autoPinEdge(toSuperviewEdge: .leading, withInset: 6) + captionIndicator.autoPinEdge(toSuperviewEdge: .top, withInset: cellBorderWidth) + captionIndicator.autoPinEdge(toSuperviewEdge: .leading, withInset: cellBorderWidth + 4) } else { captionIndicator.removeFromSuperview() } diff --git a/SignalMessaging/Views/GalleryRailView.swift b/SignalMessaging/Views/GalleryRailView.swift index 66690ab2a..6f797ea6b 100644 --- a/SignalMessaging/Views/GalleryRailView.swift +++ b/SignalMessaging/Views/GalleryRailView.swift @@ -63,17 +63,18 @@ public class GalleryRailCellView: UIView { private(set) var isSelected: Bool = false + public let cellBorderWidth: CGFloat = 2 + func setIsSelected(_ isSelected: Bool) { - let borderWidth: CGFloat = 2 self.isSelected = isSelected // Reserve space for the selection border whether or not the cell is selected. - layoutMargins = UIEdgeInsets(top: 0, left: borderWidth, bottom: 0, right: borderWidth) + layoutMargins = UIEdgeInsets(top: 0, left: cellBorderWidth, bottom: 0, right: cellBorderWidth) if isSelected { imageView.layer.borderColor = Theme.galleryHighlightColor.cgColor - imageView.layer.borderWidth = borderWidth - imageView.layer.cornerRadius = borderWidth + imageView.layer.borderWidth = cellBorderWidth + imageView.layer.cornerRadius = cellBorderWidth } else { imageView.layer.borderWidth = 0 imageView.layer.cornerRadius = 0 From 337e32a909d259af49a7b2de6b32f6ee5050d3d4 Mon Sep 17 00:00:00 2001 From: Matthew Chen <matthew@signal.org> Date: Tue, 12 Mar 2019 16:28:10 -0400 Subject: [PATCH 3/7] Fix a shadow. --- .../ViewControllers/AttachmentApprovalViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SignalMessaging/ViewControllers/AttachmentApprovalViewController.swift b/SignalMessaging/ViewControllers/AttachmentApprovalViewController.swift index a442a68aa..026aaa433 100644 --- a/SignalMessaging/ViewControllers/AttachmentApprovalViewController.swift +++ b/SignalMessaging/ViewControllers/AttachmentApprovalViewController.swift @@ -1462,6 +1462,7 @@ class MediaMessageTextToolbar: UIView, UITextViewDelegate { lengthLimitLabel.layer.shadowColor = UIColor.black.cgColor lengthLimitLabel.layer.shadowOffset = .zero lengthLimitLabel.layer.shadowOpacity = 0.8 + lengthLimitLabel.layer.shadowRadius = 2.0 lengthLimitLabel.isHidden = true return lengthLimitLabel From c0ca55b1e02e3f78adbf6ab903f49874475dcf12 Mon Sep 17 00:00:00 2001 From: Matthew Chen <matthew@signal.org> Date: Tue, 12 Mar 2019 17:04:58 -0400 Subject: [PATCH 4/7] Fix shadow on palette view. --- .../ImageEditor/ImageEditorPaletteView.swift | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorPaletteView.swift b/SignalMessaging/Views/ImageEditor/ImageEditorPaletteView.swift index e1c78ff24..e2382c395 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorPaletteView.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorPaletteView.swift @@ -81,7 +81,9 @@ public class ImageEditorPaletteView: UIView { private let imageView = UIImageView() private let selectionView = UIView() - private let selectionWrapper = OWSLayerView() + // imageWrapper is used to host the "selection view". + private let imageWrapper = OWSLayerView() + private let shadowView = UIView() private var selectionConstraint: NSLayoutConstraint? private func createContents() { @@ -89,9 +91,18 @@ public class ImageEditorPaletteView: UIView { self.isOpaque = false self.layoutMargins = .zero + shadowView.backgroundColor = .black + shadowView.layer.shadowColor = UIColor.black.cgColor + shadowView.layer.shadowRadius = 2.0 + shadowView.layer.shadowOpacity = 0.33 + shadowView.layer.shadowOffset = .zero + addSubview(shadowView) + if let image = ImageEditorPaletteView.buildPaletteGradientImage() { imageView.image = image - imageView.layer.cornerRadius = image.size.width * 0.5 + let imageRadius = image.size.width * 0.5 + imageView.layer.cornerRadius = imageRadius + shadowView.layer.cornerRadius = imageRadius imageView.clipsToBounds = true } else { owsFailDebug("Missing image.") @@ -102,29 +113,27 @@ public class ImageEditorPaletteView: UIView { imageView.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets(top: margin, left: margin, bottom: margin, right: margin)) imageView.layer.borderColor = UIColor.white.cgColor imageView.layer.borderWidth = CGHairlineWidth() - imageView.layer.shadowColor = UIColor.black.cgColor - imageView.layer.shadowRadius = 2.0 - imageView.layer.shadowOpacity = 0.33 - imageView.layer.shadowOffset = .zero - selectionWrapper.layoutCallback = { [weak self] (view) in + + imageWrapper.layoutCallback = { [weak self] (view) in guard let strongSelf = self else { return } strongSelf.updateState() } - self.addSubview(selectionWrapper) - selectionWrapper.autoPin(toEdgesOf: imageView) + addSubview(imageWrapper) + imageWrapper.autoPin(toEdgesOf: imageView) + shadowView.autoPin(toEdgesOf: imageView) selectionView.addBorder(with: .white) selectionView.layer.cornerRadius = selectionSize / 2 selectionView.autoSetDimensions(to: CGSize(width: selectionSize, height: selectionSize)) - selectionWrapper.addSubview(selectionView) + imageWrapper.addSubview(selectionView) selectionView.autoHCenterInSuperview() // There must be a better way to pin the selection view's location, // but I can't find it. let selectionConstraint = NSLayoutConstraint(item: selectionView, - attribute: .centerY, relatedBy: .equal, toItem: selectionWrapper, attribute: .top, multiplier: 1, constant: 0) + attribute: .centerY, relatedBy: .equal, toItem: imageWrapper, attribute: .top, multiplier: 1, constant: 0) selectionConstraint.autoInstall() self.selectionConstraint = selectionConstraint @@ -201,7 +210,7 @@ public class ImageEditorPaletteView: UIView { owsFailDebug("Missing selectionConstraint.") return } - let selectionY = selectionWrapper.height() * selectedValue.palettePhase + let selectionY = imageWrapper.height() * selectedValue.palettePhase selectionConstraint.constant = selectionY } From 75cfd979ba5400c81baf0ffb82d383c58e3dfe62 Mon Sep 17 00:00:00 2001 From: Matthew Chen <matthew@signal.org> Date: Tue, 12 Mar 2019 17:05:17 -0400 Subject: [PATCH 5/7] Modify brush stroke width to reflect current scale. --- .../ImageEditor/ImageEditorBrushViewController.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift b/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift index af56c8db1..ba47cb82d 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift @@ -165,9 +165,9 @@ public class ImageEditorBrushViewController: OWSViewController { let view = self.canvasView.gestureReferenceView let viewBounds = view.bounds let newSample = ImageEditorCanvasView.locationImageUnit(forLocationInView: locationInView, - viewBounds: viewBounds, - model: self.model, - transform: self.model.currentTransform()) + viewBounds: viewBounds, + model: self.model, + transform: self.model.currentTransform()) if let prevSample = self.currentStrokeSamples.last, prevSample == newSample { @@ -179,7 +179,7 @@ public class ImageEditorBrushViewController: OWSViewController { let strokeColor = paletteView.selectedValue.color // TODO: Tune stroke width. - let unitStrokeWidth = ImageEditorStrokeItem.defaultUnitStrokeWidth() + let unitStrokeWidth = ImageEditorStrokeItem.defaultUnitStrokeWidth() / self.model.currentTransform().scaling switch gestureRecognizer.state { case .began: From fedbe3a5d057c3f285c372d8b32add7011723f95 Mon Sep 17 00:00:00 2001 From: Matthew Chen <matthew@signal.org> Date: Tue, 12 Mar 2019 17:08:07 -0400 Subject: [PATCH 6/7] Fix shadow on palette view. --- SignalMessaging/Views/ImageEditor/ImageEditorPaletteView.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorPaletteView.swift b/SignalMessaging/Views/ImageEditor/ImageEditorPaletteView.swift index e2382c395..746ba5303 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorPaletteView.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorPaletteView.swift @@ -111,8 +111,7 @@ public class ImageEditorPaletteView: UIView { // We use an invisible margin to expand the hot area of this control. let margin: CGFloat = 20 imageView.autoPinEdgesToSuperviewEdges(with: UIEdgeInsets(top: margin, left: margin, bottom: margin, right: margin)) - imageView.layer.borderColor = UIColor.white.cgColor - imageView.layer.borderWidth = CGHairlineWidth() + imageView.addBorder(with: .white) imageWrapper.layoutCallback = { [weak self] (view) in guard let strongSelf = self else { From d6c91c27536ede1462b9d19280d278d38c371c69 Mon Sep 17 00:00:00 2001 From: Matthew Chen <matthew@signal.org> Date: Wed, 13 Mar 2019 11:40:43 -0400 Subject: [PATCH 7/7] Respond to CR. --- .../Views/ImageEditor/ImageEditorBrushViewController.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift b/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift index ba47cb82d..4281208dc 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorBrushViewController.swift @@ -178,7 +178,6 @@ public class ImageEditorBrushViewController: OWSViewController { } let strokeColor = paletteView.selectedValue.color - // TODO: Tune stroke width. let unitStrokeWidth = ImageEditorStrokeItem.defaultUnitStrokeWidth() / self.model.currentTransform().scaling switch gestureRecognizer.state {