Skip to content

Commit

Permalink
Grid cell background fix (#298)
Browse files Browse the repository at this point in the history
* Fixed background color of gridView to be same a container editorview

* Fixed tests

* Made BackgroundColorInheriting observable on attachment view

* Made GridView BackgroundColorObserving
  • Loading branch information
rajdeep authored Mar 20, 2024
1 parent 7c32647 commit d2f015c
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Proton/Sources/Swift/Attachment/Attachment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public protocol DynamicBoundsProviding: AnyObject {
func sizeFor(attachment: Attachment, containerSize: CGSize, lineRect: CGRect) -> CGSize
}

/// Denotes an `Attachment`content view that observes background color changes in `containerEditorView`
public protocol BackgroundColorObserving where Self: UIView {
func containerEditor(_ editor: EditorView, backgroundColorUpdated color: UIColor?, oldColor: UIColor?)
}

/// Describes an object capable of providing offsets for the `Attachment`. The value is used to offset the `Attachment` when rendered alongside the text. This may
/// be used to align the content baselines in `Attachment` content to that of it's container's content baselines.
/// - Note:
Expand Down Expand Up @@ -598,6 +603,10 @@ open class Attachment: NSTextAttachment, BoundsObserving {
guard let view = view,
view.superview == nil else { return }
editorView.richTextView.addSubview(view)
if let backgroundColorInheriting = self.contentView as? BackgroundColorObserving,
editorView.backgroundColor != nil {
backgroundColorInheriting.containerEditor(editorView, backgroundColorUpdated: editorView.backgroundColor, oldColor: nil)
}

if var editorContentView = contentView as? EditorContentView,
editorContentView.delegate == nil {
Expand Down
11 changes: 11 additions & 0 deletions Proton/Sources/Swift/Editor/EditorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,10 @@ open class EditorView: UIView {
public override var backgroundColor: UIColor? {
didSet {
richTextView.backgroundColor = backgroundColor
if backgroundColor != oldValue {
updateBackgroundInheritingViews(color: backgroundColor, oldColor: backgroundColor)
}
delegate?.editor(self, didChangeBackgroundColor: backgroundColor, oldColor: oldValue)
}
}

Expand Down Expand Up @@ -1278,6 +1282,13 @@ open class EditorView: UIView {
textViewDelegate.textViewDidChange?(richTextView)
return true
}

private func updateBackgroundInheritingViews(color: UIColor?, oldColor: UIColor?) {
let backgroundColorInheritingViews = attributedText.attachmentRanges.compactMap{ $0.attachment.contentView as? BackgroundColorObserving }
backgroundColorInheritingViews.forEach {
$0.containerEditor(self, backgroundColorUpdated: color, oldColor: oldColor)
}
}
}

extension EditorView {
Expand Down
3 changes: 3 additions & 0 deletions Proton/Sources/Swift/Editor/EditorViewDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ public protocol EditorViewDelegate: AnyObject {
/// - Returns: `true` to delete, else `false`
/// - Note: If either this or`Attachment`s property of `selectBeforeDelete` is `true`, the attachment will be shown as selected on backspace.
func editor(_ editor: EditorView, shouldSelectAttachmentOnBackspace attachment: Attachment) -> Bool?

func editor(_ editor: EditorView, didChangeBackgroundColor color: UIColor?, oldColor: UIColor?)
}

public extension EditorViewDelegate {
Expand All @@ -155,4 +157,5 @@ public extension EditorViewDelegate {
func editor(_ editor: EditorView, shouldSelectAttachmentOnBackspace attachment: Attachment) -> Bool? {
return nil
}
func editor(_ editor: EditorView, didChangeBackgroundColor color: UIColor?, oldColor: UIColor?) { }
}
21 changes: 21 additions & 0 deletions Proton/Sources/Swift/Grid/View/GridCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ protocol GridCellDelegate: AnyObject {
func cell(_ cell: GridCell, didChangeSelectionAt range: NSRange, attributes: [NSAttributedString.Key : Any], contentType: EditorContent.Name)
func cell(_ cell: GridCell, didReceiveKey key: EditorKey, at range: NSRange)
func cell(_ cell: GridCell, didChangeSelected isSelected: Bool)
func cell(_ cell: GridCell, didChangeBackgroundColor color: UIColor?, oldColor: UIColor?)
}

/// Denotes a cell in the `GridView`
Expand All @@ -122,6 +123,13 @@ open class GridCell {
/// Frame of the cell within `GridView`
public internal(set) var frame: CGRect = .zero

public var backgroundColor: UIColor? = nil {
didSet {
contentView.backgroundColor = backgroundColor
editor.backgroundColor = backgroundColor
}
}

private var selectionView: SelectionView?
private let editorInitializer: EditorInitializer

Expand Down Expand Up @@ -280,6 +288,13 @@ open class GridCell {
}
}

func updateBackgroundColorFromParent(color: UIColor?, oldColor: UIColor?) {
// check for same color is required. In absence of that, the rendering causes
// collapsed cells to still show text even though cell is collapsed
guard backgroundColor == oldColor, backgroundColor != color else { return }
backgroundColor = color
}

private func assertEditorSetupCompleted() {
guard editorSetupComplete == false,
ignoresOptimizedInit == false else {
Expand Down Expand Up @@ -322,6 +337,7 @@ open class GridCell {
editor.translatesAutoresizingMaskIntoConstraints = false
editor.boundsObserver = self
editor.delegate = self

contentView.addSubview(editor)

NSLayoutConstraint.activate([
Expand Down Expand Up @@ -367,6 +383,11 @@ extension GridCell: EditorViewDelegate {
public func editor(_ editor: EditorView, didReceiveKey key: EditorKey, at range: NSRange) {
delegate?.cell(self, didReceiveKey: key, at: range)
}

public func editor(_ editor: EditorView, didChangeBackgroundColor color: UIColor?, oldColor: UIColor?) {
contentView.backgroundColor = color
delegate?.cell(self, didChangeBackgroundColor: color, oldColor: oldColor)
}
}

extension GridCell: Equatable {
Expand Down
12 changes: 12 additions & 0 deletions Proton/Sources/Swift/Grid/View/GridContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ protocol GridContentViewDelegate: AnyObject {
func gridContentView(_ gridContentView: GridContentView, didDeleteColumnAt index: Int)

func gridContentView(_ gridContentView: GridContentView, shouldChangeColumnWidth proposedWidth: CGFloat, for columnIndex: Int) -> Bool

func gridContentView(_ gridContentView: GridContentView, cell: GridCell, didChangeBackgroundColor color: UIColor?, oldColor: UIColor?)
}

class GridContentView: UIScrollView {
Expand All @@ -68,6 +70,12 @@ class GridContentView: UIScrollView {

private(set) var selectedCells: [GridCell] = [GridCell]()

override var backgroundColor: UIColor? {
didSet {
cells.forEach { $0.updateBackgroundColorFromParent(color: backgroundColor, oldColor: oldValue) }
}
}

var numberOfColumns: Int {
grid.numberOfColumns
}
Expand Down Expand Up @@ -447,6 +455,10 @@ extension GridContentView: GridCellDelegate {
gridContentViewDelegate?.gridContentView(self, didChangeSelectionAt: range, attributes: attributes, contentType: contentType, in: cell)
}

func cell(_ cell: GridCell, didChangeBackgroundColor color: UIColor?, oldColor: UIColor?) {
gridContentViewDelegate?.gridContentView(self, cell: cell, didChangeBackgroundColor: color, oldColor: oldColor)
}

func cell(_ cell: GridCell, didChangeBounds bounds: CGRect) {
guard let row = cell.rowSpan.first else { return }
if grid.rowHeights.count > row,
Expand Down
15 changes: 15 additions & 0 deletions Proton/Sources/Swift/Grid/View/GridView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,12 @@ public class GridView: UIView {
fatalError("init(coder:) has not been implemented")
}

public override var backgroundColor: UIColor? {
didSet {
gridView.backgroundColor = backgroundColor
}
}

private func setup() {
gridView.translatesAutoresizingMaskIntoConstraints = false
leadingShadowView.translatesAutoresizingMaskIntoConstraints = false
Expand Down Expand Up @@ -655,6 +661,9 @@ extension GridView: GridContentViewDelegate {
func gridContentView(_ gridContentView: GridContentView, shouldChangeColumnWidth proposedWidth: CGFloat, for columnIndex: Int) -> Bool {
delegate?.gridView(self, shouldChangeColumnWidth: proposedWidth, for: columnIndex) ?? true
}

func gridContentView(_ gridContentView: GridContentView, cell: GridCell, didChangeBackgroundColor color: UIColor?, oldColor: UIColor?) {
}
}

class CellHandleButton: UIButton {
Expand All @@ -674,3 +683,9 @@ class CellHandleButton: UIButton {
}

extension GridView: AsyncDeferredRenderable { }

extension GridView: BackgroundColorObserving {
public func containerEditor(_ editor: EditorView, backgroundColorUpdated color: UIColor?, oldColor: UIColor?) {
backgroundColor = color
}
}
6 changes: 6 additions & 0 deletions Proton/Tests/Attachments/GridViewAttachment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,9 @@ extension GridView: AttachmentViewIdentifying {

public var type: AttachmentType { .block }
}

extension GridView: BackgroundColorObserving {
public func containerEditor(_ editor: EditorView, backgroundColorUpdated color: UIColor?, oldColor: UIColor?) {
backgroundColor = color
}
}
31 changes: 31 additions & 0 deletions Proton/Tests/Grid/GridViewAttachmentSnapshotTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,37 @@ class GridViewAttachmentSnapshotTests: SnapshotTestCase {
assertSnapshot(matching: viewController.view, as: .image, record: recordMode)
}

func testRendersGridViewAttachmentWithContainerBackgroundColor() {
let viewController = EditorTestViewController()
let editor = viewController.editor
let config = GridConfiguration(
columnsConfiguration: [
GridColumnConfiguration(width: .fixed(100)),
GridColumnConfiguration(width: .fractional(100))
],
rowsConfiguration: [
GridRowConfiguration(initialHeight: 40),
GridRowConfiguration(initialHeight: 40),
])
let attachment = GridViewAttachment(config: config)

editor.backgroundColor = .lightGray
editor.replaceCharacters(in: .zero, with: "Some text in editor")
editor.insertAttachment(in: editor.textEndRange, attachment: attachment)
editor.replaceCharacters(in: editor.textEndRange, with: "Text after grid")

let cell = attachment.view.cellAt(rowIndex: 0, columnIndex: 0)
cell?.editor.attributedText = NSAttributedString(string: "Test\nNew line\nMore text")
cell?.backgroundColor = .white

viewController.render(size: CGSize(width: 300, height: 225))
assertSnapshot(matching: viewController.view, as: .image, record: recordMode)

editor.backgroundColor = .darkGray
viewController.render(size: CGSize(width: 300, height: 225))
assertSnapshot(matching: viewController.view, as: .image, record: recordMode)
}

func testRendersGridViewAttachmentWithConstrainedFixedWidth() {
let viewController = EditorTestViewController()
let editor = viewController.editor
Expand Down
5 changes: 5 additions & 0 deletions Proton/Tests/Grid/Mocks/MockGridCellDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class MockGridCellDelegate: GridCellDelegate {
var onDidChangeSelection: ((GridCell, NSRange, [NSAttributedString.Key : Any], EditorContent.Name) -> Void)?
var onDidReceiveKey: ((GridCell, EditorKey, NSRange) -> Void)?
var onDidChangeSelected: ((GridCell, Bool) -> Void)?
var onDidChangeBackgroundColor: ((GridCell, UIColor?, UIColor?) -> Void)?


func cell(_ cell: GridCell, didChangeBounds bounds: CGRect) {
Expand Down Expand Up @@ -59,4 +60,8 @@ class MockGridCellDelegate: GridCellDelegate {
func cell(_ cell: GridCell, didChangeSelected isSelected: Bool) {
onDidChangeSelected?(cell, isSelected)
}

func cell(_ cell: GridCell, didChangeBackgroundColor color: UIColor?, oldColor: UIColor?) {
onDidChangeBackgroundColor?(cell, color, oldColor)
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit d2f015c

Please sign in to comment.