|
@@ -177,10 +177,6 @@ final class DrawPrintOverlayView: NSView, AppearanceRefreshable {
|
|
|
self?.pickImage()
|
|
self?.pickImage()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- canvasView.onUndoStateChanged = { [weak self] canUndo, canRedo in
|
|
|
|
|
- self?.canvasView.updateUndoButtons(canUndo: canUndo, canRedo: canRedo)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
canvasContainer.addSubview(canvasView)
|
|
canvasContainer.addSubview(canvasView)
|
|
|
|
|
|
|
|
addSubview(backButton)
|
|
addSubview(backButton)
|
|
@@ -292,11 +288,6 @@ final class BlankCanvasView: NSView, AppearanceRefreshable {
|
|
|
redoButton.refreshAppearance()
|
|
redoButton.refreshAppearance()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- func updateUndoButtons(canUndo: Bool, canRedo: Bool) {
|
|
|
|
|
- undoButton.setActionEnabled(canUndo)
|
|
|
|
|
- redoButton.setActionEnabled(canRedo)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
private func setup() {
|
|
private func setup() {
|
|
|
wantsLayer = true
|
|
wantsLayer = true
|
|
|
layer?.cornerRadius = AppTheme.contentPanelCornerRadius
|
|
layer?.cornerRadius = AppTheme.contentPanelCornerRadius
|
|
@@ -324,6 +315,26 @@ final class BlankCanvasView: NSView, AppearanceRefreshable {
|
|
|
])
|
|
])
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ override func hitTest(_ point: NSPoint) -> NSView? {
|
|
|
|
|
+ for button in [redoButton, undoButton] {
|
|
|
|
|
+ let localPoint = convert(point, to: button)
|
|
|
|
|
+ if let hit = button.hitTest(localPoint) {
|
|
|
|
|
+ return hit
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return super.hitTest(point)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private func bringUndoButtonsToFront() {
|
|
|
|
|
+ addSubview(redoButton, positioned: .above, relativeTo: nil)
|
|
|
|
|
+ addSubview(undoButton, positioned: .below, relativeTo: redoButton)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private func updateUndoButtons(canUndo: Bool, canRedo: Bool) {
|
|
|
|
|
+ undoButton.setActionEnabled(canUndo)
|
|
|
|
|
+ redoButton.setActionEnabled(canRedo)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
override func draw(_ dirtyRect: NSRect) {
|
|
override func draw(_ dirtyRect: NSRect) {
|
|
|
NSColor.white.setFill()
|
|
NSColor.white.setFill()
|
|
|
NSBezierPath(
|
|
NSBezierPath(
|
|
@@ -364,6 +375,9 @@ final class BlankCanvasView: NSView, AppearanceRefreshable {
|
|
|
|
|
|
|
|
override func mouseDown(with event: NSEvent) {
|
|
override func mouseDown(with event: NSEvent) {
|
|
|
let point = convert(event.locationInWindow, from: nil)
|
|
let point = convert(event.locationInWindow, from: nil)
|
|
|
|
|
+ if undoButton.frame.contains(point) || redoButton.frame.contains(point) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
switch activeTool {
|
|
switch activeTool {
|
|
|
case .draw:
|
|
case .draw:
|
|
@@ -487,6 +501,7 @@ final class BlankCanvasView: NSView, AppearanceRefreshable {
|
|
|
undoStack.append(CanvasSnapshot(strokes: strokes, texts: textItems, images: imageItems))
|
|
undoStack.append(CanvasSnapshot(strokes: strokes, texts: textItems, images: imageItems))
|
|
|
redoStack.removeAll()
|
|
redoStack.removeAll()
|
|
|
if undoStack.count > 50 { undoStack.removeFirst() }
|
|
if undoStack.count > 50 { undoStack.removeFirst() }
|
|
|
|
|
+ notifyUndoState()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private func undo() {
|
|
private func undo() {
|
|
@@ -511,13 +526,16 @@ final class BlankCanvasView: NSView, AppearanceRefreshable {
|
|
|
for item in textItems {
|
|
for item in textItems {
|
|
|
installTextField(for: item)
|
|
installTextField(for: item)
|
|
|
}
|
|
}
|
|
|
|
|
+ bringUndoButtonsToFront()
|
|
|
needsDisplay = true
|
|
needsDisplay = true
|
|
|
notifyUndoState()
|
|
notifyUndoState()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private func notifyUndoState() {
|
|
private func notifyUndoState() {
|
|
|
- onUndoStateChanged?(!undoStack.isEmpty, !redoStack.isEmpty)
|
|
|
|
|
- updateUndoButtons(canUndo: !undoStack.isEmpty, canRedo: !redoStack.isEmpty)
|
|
|
|
|
|
|
+ let canUndo = !undoStack.isEmpty
|
|
|
|
|
+ let canRedo = !redoStack.isEmpty
|
|
|
|
|
+ onUndoStateChanged?(canUndo, canRedo)
|
|
|
|
|
+ updateUndoButtons(canUndo: canUndo, canRedo: canRedo)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private func installTextField(for item: CanvasTextData) {
|
|
private func installTextField(for item: CanvasTextData) {
|
|
@@ -533,6 +551,7 @@ final class BlankCanvasView: NSView, AppearanceRefreshable {
|
|
|
field.target = self
|
|
field.target = self
|
|
|
field.action = #selector(textFieldEdited(_:))
|
|
field.action = #selector(textFieldEdited(_:))
|
|
|
addSubview(field)
|
|
addSubview(field)
|
|
|
|
|
+ bringUndoButtonsToFront()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@objc private func textFieldEdited(_ sender: NSTextField) {
|
|
@objc private func textFieldEdited(_ sender: NSTextField) {
|
|
@@ -899,6 +918,8 @@ private final class CanvasHistoryButton: NSControl, AppearanceRefreshable {
|
|
|
actionEnabled = enabled
|
|
actionEnabled = enabled
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ override func mouseDown(with event: NSEvent) {}
|
|
|
|
|
+
|
|
|
override func mouseUp(with event: NSEvent) {
|
|
override func mouseUp(with event: NSEvent) {
|
|
|
guard actionEnabled, bounds.contains(convert(event.locationInWindow, from: nil)) else { return }
|
|
guard actionEnabled, bounds.contains(convert(event.locationInWindow, from: nil)) else { return }
|
|
|
onClick?()
|
|
onClick?()
|