Skip to content

Commit 333e68b

Browse files
authored
Decelect cells after merge. Also added isSelectable to GridCell (#261)
1 parent 0ed61a1 commit 333e68b

File tree

3 files changed

+65
-6
lines changed

3 files changed

+65
-6
lines changed

Diff for: Proton/Sources/Swift/Grid/View/GridCell.swift

+5-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ open class GridCell {
137137
public var isSelected: Bool {
138138
get { selectionView?.superview != nil }
139139
set {
140-
guard newValue != isSelected else { return }
140+
guard isSelectable,
141+
newValue != isSelected else { return }
141142
if newValue {
142143
selectionView?.addTo(parent: contentView)
143144
} else {
@@ -147,6 +148,9 @@ open class GridCell {
147148
}
148149
}
149150

151+
/// Controls if the cell can be selected or not.
152+
public var isSelectable: Bool = true
153+
150154
private(set) var editorSetupComplete = false
151155
private var _editor: EditorView?
152156
/// Editor within the cell

Diff for: Proton/Sources/Swift/Grid/View/GridContentView.swift

+12-5
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ class GridContentView: UIScrollView {
185185
func selectCells(_ cells: [GridCell]) {
186186
deselectCells()
187187
// selectedCells.append(contentsOf: cells)
188+
cells.first?.editor.setFocus()
188189
cells.forEach { $0.isSelected = true }
189190
}
190191

@@ -200,12 +201,15 @@ class GridContentView: UIScrollView {
200201
func merge(cells: [GridCell]) -> GridCell? {
201202
let mergedCell = grid.merge(cells: cells)
202203
invalidateCellLayout()
204+
deselectCells()
203205
return mergedCell
204206
}
205207

206208
func split(cell: GridCell) -> [GridCell] {
207209
let cells = grid.split(cell: cell)
208210
invalidateCellLayout()
211+
// First cell is the existing merged cell. Others are added as new.
212+
deselectCells()
209213
return cells
210214
}
211215

@@ -290,9 +294,11 @@ class GridContentView: UIScrollView {
290294
deselectCurrentSelection()
291295
}
292296

293-
if sender.state == .began ||
294-
sender.state == .changed {
295-
selectCellsInLocation(location)
297+
if sender.state == .began || sender.state == .changed {
298+
let cell = selectCellsInLocation(location)
299+
if sender.state == .began {
300+
cell?.editor.setFocus()
301+
}
296302
let velocity = sender.velocity(in: self)
297303
let updatedOffset = contentOffset.x + (velocity.x/100)
298304
if updatedOffset >= 0, // prevent out of bounds scroll to left
@@ -302,9 +308,10 @@ class GridContentView: UIScrollView {
302308
}
303309
}
304310

305-
func selectCellsInLocation(_ location: CGPoint) {
306-
guard let cell = cells.first(where: { $0.frame.contains(location) }) else { return }
311+
func selectCellsInLocation(_ location: CGPoint) -> GridCell? {
312+
guard let cell = cells.first(where: { $0.frame.contains(location) }) else { return nil }
307313
cell.isSelected = true
314+
return cell
308315
}
309316

310317
func deselectCurrentSelection() {

Diff for: Proton/Tests/Grid/GridViewTests.swift

+48
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,52 @@ class GridViewTests: XCTestCase {
219219
gridView.selectCells(cellsToSelect)
220220
waitForExpectations(timeout: 1.0)
221221
}
222+
223+
func testDeselectsCellAfterMerge() {
224+
let gridView = GridView(config: config)
225+
let delegate = MockGridViewDelegate()
226+
gridView.delegate = delegate
227+
gridView.gridView.willMove(toWindow: UIWindow())
228+
229+
let cells = gridView.cells.filter({ $0.rowSpan.first ?? 0 < 2 && $0.columnSpan.first ?? 0 < 2 })
230+
gridView.selectCells(cells)
231+
232+
XCTAssertEqual(gridView.selectedCells.count, 4)
233+
gridView.merge(cells: cells)
234+
XCTAssertEqual(gridView.selectedCells.count, 0)
235+
}
236+
237+
func testDeselectsCellAfterSplit() {
238+
let gridView = GridView(config: config)
239+
let delegate = MockGridViewDelegate()
240+
gridView.delegate = delegate
241+
gridView.gridView.willMove(toWindow: UIWindow())
242+
243+
let cells = gridView.cells.filter({ $0.rowSpan.first ?? 0 < 2 && $0.columnSpan.first ?? 0 < 2 })
244+
gridView.selectCells(cells)
245+
246+
XCTAssertEqual(gridView.selectedCells.count, 4)
247+
XCTAssertEqual(gridView.cells.count, 6)
248+
gridView.merge(cells: cells)
249+
XCTAssertEqual(gridView.cells.count, 3)
250+
gridView.selectCells([cells[0]])
251+
gridView.split(cell: cells[0])
252+
XCTAssertEqual(gridView.cells.count, 6)
253+
XCTAssertEqual(gridView.selectedCells.count, 0)
254+
}
255+
256+
func testIgnoresNonSelectableCellsOnSelection() {
257+
let gridView = GridView(config: config)
258+
let delegate = MockGridViewDelegate()
259+
gridView.delegate = delegate
260+
gridView.gridView.willMove(toWindow: UIWindow())
261+
262+
gridView.cells.filter({ $0.rowSpan.first ?? 0 < 2 && $0.columnSpan.first ?? 0 < 1 }).forEach {
263+
$0.isSelectable = false
264+
}
265+
gridView.selectCells(gridView.cells.filter({ $0.rowSpan.first ?? 0 < 2 && $0.columnSpan.first ?? 0 < 2 }))
266+
XCTAssertEqual(gridView.selectedCells.count, 2)
267+
XCTAssertEqual(gridView.selectedCells[0].id, "{[0],[1]}")
268+
XCTAssertEqual(gridView.selectedCells[1].id, "{[1],[1]}")
269+
}
222270
}

0 commit comments

Comments
 (0)