Sfoglia il codice sorgente

Fix draw canvas undo and redo buttons not responding to clicks.

Route button hits before drawing gestures, keep controls visible above text fields, and refresh enabled state when snapshots are pushed.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 1 mese fa
parent
commit
9e41126dab
1 ha cambiato i file con 32 aggiunte e 11 eliminazioni
  1. 32 11
      smart_printer/DrawPrintView.swift

+ 32 - 11
smart_printer/DrawPrintView.swift

@@ -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?()