Skip to content

Commit 7100764

Browse files
committed
feat(screenshot): add guide line sub-mode to ruler measurement tool
- add MeasureMode.guide as the 6th ruler sub-mode; single click places a horizontal guide, Shift+click places a vertical guide spanning the full canvas width/height - render guide as a dashed line using canvasBounds for edge-to-edge extent; label shows x/y coordinate in px or pt matching current unit - encode orientation in points[0].x (>0.5 = vertical) to avoid adding a new shape field - add guide button to option row (SF Symbol: line.diagonal); update contentWidth to accommodate 6 mode buttons - add i18n keys for guide line in en/zh-Hans/zh-Hant/ja
1 parent 0650a01 commit 7100764

3 files changed

Lines changed: 53 additions & 3 deletions

File tree

DockMasterPro/Plugins/ScreenshotPlugin/ScreenshotAnnotationModel.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ enum MeasureMode: Equatable {
3030
case coordinate // 坐标标注(单击)
3131
case dimension // 宽高标注(拖拽矩形)
3232
case polyline // 折线多段距离(多次点击,双击结束)
33+
case guide // 参考线(单击放水平线,Shift+单击放垂直线,贯穿全图)
3334
}
3435

3536
// MARK: - Annotation Tool
@@ -846,6 +847,39 @@ struct AnnotationShape {
846847
drawPill("Σ " + distLabel(total),
847848
cx: last.x, cy: last.y + capLen + labelFontSize + 6)
848849
}
850+
851+
// ── Mode 6: Guide Line ────────────────────────────────────────────
852+
case .guide:
853+
guard let canvas = shape.canvasBounds, canvas.width > 0, canvas.height > 0 else { return }
854+
let isVertical = shape.points?.first.map { $0.x > 0.5 } ?? false
855+
// points[0].x > 0.5 → vertical; otherwise horizontal (encoded at commit time)
856+
let path = NSBezierPath()
857+
if isVertical {
858+
let x = shape.startPoint.x
859+
path.move(to: NSPoint(x: x, y: canvas.minY))
860+
path.line(to: NSPoint(x: x, y: canvas.maxY))
861+
let labelVal = shape.rulerUnit == .px
862+
? Int(x * shape.scaleFactor)
863+
: Int(x)
864+
drawPill("x = \(labelVal)\(shape.rulerUnit == .px ? "px" : "pt")",
865+
cx: x + labelFontSize + 4,
866+
cy: canvas.minY + labelFontSize * 2)
867+
} else {
868+
let y = shape.startPoint.y
869+
path.move(to: NSPoint(x: canvas.minX, y: y))
870+
path.line(to: NSPoint(x: canvas.maxX, y: y))
871+
let labelVal = shape.rulerUnit == .px
872+
? Int(y * shape.scaleFactor)
873+
: Int(y)
874+
drawPill("y = \(labelVal)\(shape.rulerUnit == .px ? "px" : "pt")",
875+
cx: canvas.minX + labelFontSize * 3 + 4,
876+
cy: y + labelFontSize / 2 + 4)
877+
}
878+
path.lineWidth = max(1, lw * 0.7)
879+
path.setLineDash([6, 4], count: 2, phase: 0)
880+
path.lineCapStyle = .round
881+
color.withAlphaComponent(0.85).setStroke()
882+
path.stroke()
849883
}
850884
}
851885

DockMasterPro/Plugins/ScreenshotPlugin/ScreenshotAnnotationView.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,19 @@ final class ScreenshotAnnotationView: NSView, NSTextFieldDelegate {
306306
shape.rulerUnit = session.currentRulerUnit
307307
session.commit(shape)
308308
onSessionChanged?(); onShapeCommitted?(); needsDisplay = true
309+
310+
case .guide:
311+
// 单击放水平线,Shift+单击放垂直线;canvasBounds 记录当前画布尺寸
312+
let isVertical = event.modifierFlags.contains(.shift)
313+
var shape = AnnotationShape(tool: .ruler, startPoint: pt, endPoint: pt,
314+
color: session.currentColor, lineWidth: session.currentLineWidth,
315+
points: [NSPoint(x: isVertical ? 1.0 : 0.0, y: 0)])
316+
shape.measureMode = .guide
317+
shape.scaleFactor = window?.screen?.backingScaleFactor ?? 1.0
318+
shape.rulerUnit = session.currentRulerUnit
319+
shape.canvasBounds = bounds
320+
session.commit(shape)
321+
onSessionChanged?(); onShapeCommitted?(); needsDisplay = true
309322
case .polyline:
310323
if event.clickCount == 2 {
311324
// 双击:提交折线

DockMasterPro/Plugins/ScreenshotPlugin/ScreenshotEditToolbar.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ final class ScreenshotEditOptionRow: NSView {
564564
let dots = CGFloat(AnnotationSession.presetColors.count) * dotSize
565565
+ CGFloat(AnnotationSession.presetColors.count - 1) * dotGap
566566
let colorSection = dots + afterDots + pickerSize
567-
let modeBtns = 5 * lbSize + 4 * lbGap
567+
let modeBtns = 6 * lbSize + 5 * lbGap
568568
let unitBtns = 2 * lbSize + lbGap
569569
return leftPad + colorSection + afterPicker + lbs + groupGap + modeBtns + groupGap + unitBtns + rightPad
570570
}
@@ -961,12 +961,13 @@ final class ScreenshotEditOptionRow: NSView {
961961
}
962962
x += Self.groupGap - Self.lbGap
963963

964-
// 测量模式按钮(5 种)
964+
// 测量模式按钮(6 种)
965965
for (mode, key) in [(MeasureMode.ruler, "edit.rl.mode.ruler"),
966966
(MeasureMode.angle, "edit.rl.mode.angle"),
967967
(MeasureMode.coordinate, "edit.rl.mode.coord"),
968968
(MeasureMode.dimension, "edit.rl.mode.dim"),
969-
(MeasureMode.polyline, "edit.rl.mode.poly")] {
969+
(MeasureMode.polyline, "edit.rl.mode.poly"),
970+
(MeasureMode.guide, "edit.rl.mode.guide")] {
970971
let btn = makeRulerModeBtn(mode: mode, tooltip: L(key),
971972
frame: NSRect(x: x, y: lbY, width: lbs, height: lbs))
972973
rulerModeBtns.append((mode, btn))
@@ -1491,6 +1492,7 @@ final class ScreenshotEditOptionRow: NSView {
14911492
case .coordinate: symbolName = "mappin"
14921493
case .dimension: symbolName = "arrow.left.and.right"
14931494
case .polyline: symbolName = "point.3.connected.trianglepath.dotted"
1495+
case .guide: symbolName = "line.diagonal"
14941496
}
14951497
return NSImage(systemSymbolName: symbolName, accessibilityDescription: nil)
14961498
?? NSImage(systemSymbolName: "ruler", accessibilityDescription: nil)!
@@ -2183,6 +2185,7 @@ final class ScreenshotEditOptionRow: NSView {
21832185
"edit.rl.mode.coord": ["en": "Coordinate", "zh-Hans": "坐标", "zh-Hant": "座標", "ja": "座標"],
21842186
"edit.rl.mode.dim": ["en": "Dimension", "zh-Hans": "宽高", "zh-Hant": "寬高", "ja": "サイズ"],
21852187
"edit.rl.mode.poly": ["en": "Polyline", "zh-Hans": "折线", "zh-Hant": "折線", "ja": "折れ線"],
2188+
"edit.rl.mode.guide": ["en": "Guide Line", "zh-Hans": "参考线", "zh-Hant": "參考線", "ja": "ガイド線"],
21862189
"edit.rl.unit.px": ["en": "Pixels", "zh-Hans": "像素", "zh-Hant": "像素", "ja": "ピクセル"],
21872190
"edit.rl.unit.pt": ["en": "Points", "zh-Hans": "", "zh-Hant": "", "ja": "ポイント"],
21882191
]

0 commit comments

Comments
 (0)