Use narrow change events in image editor.

pull/1/head
Matthew Chen 7 years ago
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 {
// Don't animate changes.
CATransaction.begin()
CATransaction.setDisableActions(true)
for layer in contentLayerMap.values {
layer.removeFromSuperlayer()
}
contentLayers.removeAll()
contentLayerMap.removeAll()
guard bounds.width > 0,
bounds.height > 0 else {
return
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)
for item in model.items() {
guard let layer = ImageEditorView.layerForItem(item: item,
viewSize: bounds.size) else {
continue
// 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 {
self.layer.addSublayer(layer)
contentLayers.append(layer)
// 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…
Cancel
Save