Files
SnipMC/Sources/Editor/AnnotationDocument.swift
T
marcoandClaude Opus 4.6 062285abbf Add image editor with annotation tools
Integrates an editor accessible via "Letzte Aufnahme bearbeiten…" or
"Bild bearbeiten…" in the menu bar. Supports arrow, rectangle, ellipse,
and text annotations with color picker, line width, undo/redo, and
export to file or clipboard.

New files in Sources/Editor/:
- AnnotationItem/Document: data model and state management
- AnnotationCanvasView: NSView with CG rendering and mouse interaction
- AnnotationRenderer: shared rendering for canvas and image export
- EditorToolbarView: SwiftUI toolbar with tool selection and actions
- EditorWindowController: window lifecycle following SettingsWindowController pattern

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-01 17:44:20 +02:00

57 lines
1.4 KiB
Swift

import AppKit
import Foundation
@Observable
final class AnnotationDocument {
var items: [AnnotationItem] = []
var selectedItemID: UUID?
var currentTool: AnnotationKind = .arrow
var currentColor: NSColor = .systemRed
var currentLineWidth: CGFloat = 3
private var undoStack: [[AnnotationItem]] = []
private var redoStack: [[AnnotationItem]] = []
var canUndo: Bool { !undoStack.isEmpty }
var canRedo: Bool { !redoStack.isEmpty }
func pushUndo() {
undoStack.append(items)
redoStack.removeAll()
}
func undo() {
guard let previous = undoStack.popLast() else { return }
redoStack.append(items)
items = previous
selectedItemID = nil
}
func redo() {
guard let next = redoStack.popLast() else { return }
undoStack.append(items)
items = next
selectedItemID = nil
}
func addItem(_ item: AnnotationItem) {
pushUndo()
items.append(item)
selectedItemID = item.id
}
func deleteSelected() {
guard let id = selectedItemID else { return }
pushUndo()
items.removeAll { $0.id == id }
selectedItemID = nil
}
func moveSelected(by delta: CGSize) {
guard let id = selectedItemID,
let index = items.firstIndex(where: { $0.id == id }) else { return }
items[index].rect.origin.x += delta.width
items[index].rect.origin.y += delta.height
}
}