Use narrow change events in image editor.
This commit is contained in:
parent
f224c2130a
commit
2f95413bcf
@ -139,6 +139,10 @@ public class OrderedDictionary<ValueType>: NSObject {
|
||||
return OrderedDictionary(keyValueMap: keyValueMap, orderedKeys: orderedKeys)
|
||||
}
|
||||
|
||||
public func value(forKey key: KeyType) -> ValueType? {
|
||||
return keyValueMap[key]
|
||||
}
|
||||
|
||||
public func append(key: KeyType, value: ValueType) {
|
||||
if keyValueMap[key] != nil {
|
||||
owsFailDebug("Unexpected duplicate key in key map: \(key)")
|
||||
@ -239,6 +243,11 @@ public class ImageEditorContents: NSObject {
|
||||
return ImageEditorContents(itemMap: itemMap.clone())
|
||||
}
|
||||
|
||||
@objc
|
||||
public func item(forId itemId: String) -> ImageEditorItem? {
|
||||
return itemMap.value(forKey: itemId)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func append(item: ImageEditorItem) {
|
||||
Logger.verbose("\(item.itemId)")
|
||||
@ -300,6 +309,7 @@ private class ImageEditorOperation: NSObject {
|
||||
@objc
|
||||
public protocol ImageEditorModelDelegate: class {
|
||||
func imageEditorModelDidChange()
|
||||
func imageEditorModelDidChange(changedItemIds: [String])
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
@ -360,6 +370,11 @@ public class ImageEditorModel: NSObject {
|
||||
return contents.items()
|
||||
}
|
||||
|
||||
@objc
|
||||
public func item(forId itemId: String) -> ImageEditorItem? {
|
||||
return contents.item(forId: itemId)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func canUndo() -> Bool {
|
||||
return !undoStack.isEmpty
|
||||
@ -382,6 +397,7 @@ public class ImageEditorModel: NSObject {
|
||||
|
||||
self.contents = undoOperation.contents
|
||||
|
||||
// We could diff here and yield a more narrow change event.
|
||||
delegate?.imageEditorModelDidChange()
|
||||
}
|
||||
|
||||
@ -397,6 +413,7 @@ public class ImageEditorModel: NSObject {
|
||||
|
||||
self.contents = redoOperation.contents
|
||||
|
||||
// We could diff here and yield a more narrow change event.
|
||||
delegate?.imageEditorModelDidChange()
|
||||
}
|
||||
|
||||
@ -404,7 +421,7 @@ public class ImageEditorModel: NSObject {
|
||||
public func append(item: ImageEditorItem) {
|
||||
performAction({ (newContents) in
|
||||
newContents.append(item: item)
|
||||
})
|
||||
}, changedItemIds: [item.itemId])
|
||||
}
|
||||
|
||||
@objc
|
||||
@ -420,10 +437,11 @@ public class ImageEditorModel: NSObject {
|
||||
public func remove(item: ImageEditorItem) {
|
||||
performAction({ (newContents) in
|
||||
newContents.remove(item: item)
|
||||
})
|
||||
}, changedItemIds: [item.itemId])
|
||||
}
|
||||
|
||||
private func performAction(_ action: (ImageEditorContents) -> Void,
|
||||
changedItemIds: [String],
|
||||
suppressUndo: Bool = false) {
|
||||
if !suppressUndo {
|
||||
let undoOperation = ImageEditorOperation(contents: contents)
|
||||
@ -435,6 +453,6 @@ public class ImageEditorModel: NSObject {
|
||||
action(newContents)
|
||||
contents = newContents
|
||||
|
||||
delegate?.imageEditorModelDidChange()
|
||||
delegate?.imageEditorModelDidChange(changedItemIds: changedItemIds)
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,8 +101,6 @@ public class ImageEditorView: UIView, ImageEditorModelDelegate {
|
||||
public func handleTouchGesture(_ gestureRecognizer: UIGestureRecognizer) {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
Logger.verbose("\(NSStringForUIGestureRecognizerState(gestureRecognizer.state))")
|
||||
|
||||
let removeCurrentStroke = {
|
||||
if let stroke = self.currentStroke {
|
||||
self.model.remove(item: stroke)
|
||||
@ -163,13 +161,17 @@ public class ImageEditorView: UIView, ImageEditorModelDelegate {
|
||||
// MARK: - ImageEditorModelDelegate
|
||||
|
||||
public func imageEditorModelDidChange() {
|
||||
// TODO: We eventually want to narrow our change events
|
||||
// to reflect the specific item(s) which changed.
|
||||
updateAllContent()
|
||||
|
||||
updateButtons()
|
||||
}
|
||||
|
||||
public func imageEditorModelDidChange(changedItemIds: [String]) {
|
||||
updateContent(changedItemIds: changedItemIds)
|
||||
|
||||
updateButtons()
|
||||
}
|
||||
|
||||
// MARK: - Accessor Overrides
|
||||
|
||||
@objc public override var bounds: CGRect {
|
||||
@ -190,33 +192,71 @@ public class ImageEditorView: UIView, ImageEditorModelDelegate {
|
||||
|
||||
// MARK: - Content
|
||||
|
||||
var contentLayers = [CALayer]()
|
||||
var contentLayerMap = [String: CALayer]()
|
||||
|
||||
internal func updateAllContent() {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
for layer in contentLayers {
|
||||
layer.removeFromSuperlayer()
|
||||
}
|
||||
contentLayers.removeAll()
|
||||
|
||||
guard bounds.width > 0,
|
||||
bounds.height > 0 else {
|
||||
return
|
||||
}
|
||||
|
||||
// Don't animate changes.
|
||||
CATransaction.begin()
|
||||
CATransaction.setDisableActions(true)
|
||||
|
||||
for item in model.items() {
|
||||
guard let layer = ImageEditorView.layerForItem(item: item,
|
||||
viewSize: bounds.size) else {
|
||||
continue
|
||||
}
|
||||
for layer in contentLayerMap.values {
|
||||
layer.removeFromSuperlayer()
|
||||
}
|
||||
contentLayerMap.removeAll()
|
||||
|
||||
self.layer.addSublayer(layer)
|
||||
contentLayers.append(layer)
|
||||
if bounds.width > 0,
|
||||
bounds.height > 0 {
|
||||
|
||||
for item in model.items() {
|
||||
guard let layer = ImageEditorView.layerForItem(item: item,
|
||||
viewSize: bounds.size) else {
|
||||
continue
|
||||
}
|
||||
|
||||
self.layer.addSublayer(layer)
|
||||
contentLayerMap[item.itemId] = layer
|
||||
}
|
||||
}
|
||||
|
||||
CATransaction.commit()
|
||||
}
|
||||
|
||||
internal func updateContent(changedItemIds: [String]) {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
// Don't animate changes.
|
||||
CATransaction.begin()
|
||||
CATransaction.setDisableActions(true)
|
||||
|
||||
// Remove all changed items.
|
||||
for itemId in changedItemIds {
|
||||
if let layer = contentLayerMap[itemId] {
|
||||
layer.removeFromSuperlayer()
|
||||
}
|
||||
contentLayerMap.removeValue(forKey: itemId)
|
||||
}
|
||||
|
||||
if bounds.width > 0,
|
||||
bounds.height > 0 {
|
||||
|
||||
// Create layers for inserted and updated items.
|
||||
for itemId in changedItemIds {
|
||||
guard let item = model.item(forId: itemId) else {
|
||||
// Item was deleted.
|
||||
continue
|
||||
}
|
||||
|
||||
// Item was inserted or updated.
|
||||
guard let layer = ImageEditorView.layerForItem(item: item,
|
||||
viewSize: bounds.size) else {
|
||||
continue
|
||||
}
|
||||
|
||||
self.layer.addSublayer(layer)
|
||||
contentLayerMap[item.itemId] = layer
|
||||
}
|
||||
}
|
||||
|
||||
CATransaction.commit()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user