Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de642ad692 | ||
|
|
8b27263962 |
@@ -91,9 +91,9 @@ final class CaptureModel: ObservableObject {
|
||||
/// Drag selection rect in IMAGE point space (nil = none)
|
||||
@Published var selection: CGRect?
|
||||
/// Freehand drawing strokes in IMAGE point space
|
||||
@Published var strokes: [[CGPoint]] = []
|
||||
@Published var strokes: [Stroke] = []
|
||||
/// Redo stack of removed strokes
|
||||
@Published var redoStack: [[CGPoint]] = []
|
||||
@Published var redoStack: [Stroke] = []
|
||||
/// Whether the pen is active (drag draws instead of selecting)
|
||||
@Published var isDrawing = false
|
||||
/// Current drawing color
|
||||
@@ -101,6 +101,12 @@ final class CaptureModel: ObservableObject {
|
||||
/// Stroke thickness in points (image space)
|
||||
@Published var strokeWidth: CGFloat = 3.0
|
||||
|
||||
struct Stroke {
|
||||
let points: [CGPoint]
|
||||
let width: CGFloat
|
||||
let color: NSColor
|
||||
}
|
||||
|
||||
enum CaptureMode {
|
||||
case screenshot
|
||||
case text
|
||||
@@ -143,26 +149,33 @@ final class CaptureModel: ObservableObject {
|
||||
let ctx = NSGraphicsContext.current!.cgContext
|
||||
// CGImage draws with a flipped Y in NSGraphicsContext
|
||||
ctx.draw(image, in: NSRect(origin: .zero, size: size))
|
||||
drawColor.setStroke()
|
||||
ctx.setLineWidth(strokeWidth)
|
||||
// Strokes are stored in TOP-LEFT image coordinates (from the SwiftUI
|
||||
// canvas), but the CGContext uses a BOTTOM-LEFT origin. Flip Y so the
|
||||
// strokes land where they were drawn.
|
||||
ctx.saveGState()
|
||||
ctx.translateBy(x: 0, y: size.height)
|
||||
ctx.scaleBy(x: 1, y: -1)
|
||||
ctx.setLineCap(.round)
|
||||
ctx.setLineJoin(.round)
|
||||
for stroke in strokes {
|
||||
guard stroke.count > 1 else { continue }
|
||||
guard stroke.points.count > 1 else { continue }
|
||||
stroke.color.setStroke()
|
||||
ctx.setLineWidth(stroke.width)
|
||||
ctx.beginPath()
|
||||
ctx.move(to: stroke[0])
|
||||
for point in stroke.dropFirst() {
|
||||
ctx.move(to: stroke.points[0])
|
||||
for point in stroke.points.dropFirst() {
|
||||
ctx.addLine(to: point)
|
||||
}
|
||||
ctx.strokePath()
|
||||
}
|
||||
ctx.restoreGState()
|
||||
NSGraphicsContext.restoreGraphicsState()
|
||||
return rep.cgImage ?? image
|
||||
}
|
||||
|
||||
func addStroke(_ points: [CGPoint]) {
|
||||
guard points.count > 1 else { return }
|
||||
strokes.append(points)
|
||||
strokes.append(Stroke(points: points, width: strokeWidth, color: drawColor))
|
||||
redoStack = []
|
||||
}
|
||||
|
||||
@@ -387,6 +400,16 @@ struct ResultView: View {
|
||||
.disabled(!model.canRedo)
|
||||
.keyboardShortcut("z", modifiers: [.command, .shift])
|
||||
.help("Redo stroke (⌘⇧Z)")
|
||||
|
||||
Button {
|
||||
model.clearAnnotations()
|
||||
} label: {
|
||||
Label("Clear", systemImage: "eraser")
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.controlSize(.small)
|
||||
.disabled(model.strokes.isEmpty)
|
||||
.help("Remove all drawn annotations")
|
||||
}
|
||||
.padding(.horizontal, 14)
|
||||
.padding(.vertical, 8)
|
||||
@@ -490,15 +513,15 @@ struct ScreenshotPane: View {
|
||||
|
||||
// Completed strokes
|
||||
Canvas { context, _ in
|
||||
var path = Path()
|
||||
for stroke in model.strokes {
|
||||
guard stroke.count > 1 else { continue }
|
||||
path.move(to: CGPoint(x: origin.x + stroke[0].x * scale, y: origin.y + stroke[0].y * scale))
|
||||
for point in stroke.dropFirst() {
|
||||
guard stroke.points.count > 1 else { continue }
|
||||
var path = Path()
|
||||
path.move(to: CGPoint(x: origin.x + stroke.points[0].x * scale, y: origin.y + stroke.points[0].y * scale))
|
||||
for point in stroke.points.dropFirst() {
|
||||
path.addLine(to: CGPoint(x: origin.x + point.x * scale, y: origin.y + point.y * scale))
|
||||
}
|
||||
context.stroke(path, with: .color(Color(nsColor: stroke.color)), lineWidth: stroke.width)
|
||||
}
|
||||
context.stroke(path, with: .color(Color(nsColor: model.drawColor)), lineWidth: model.strokeWidth)
|
||||
}
|
||||
.allowsHitTesting(false)
|
||||
|
||||
|
||||
+2
-2
@@ -108,9 +108,9 @@ cat > "$APP/Contents/Info.plist" <<'PLIST'
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>Icon</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.4.1</string>
|
||||
<string>1.4.3</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>41</string>
|
||||
<string>43</string>
|
||||
<key>LSUIElement</key>
|
||||
<true/>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
|
||||
Reference in New Issue
Block a user