Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 32 additions & 7 deletions Free Ruler/HorizontalRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,27 +114,52 @@ class HorizontalRule: RuleView {
let number = mouseTickX
let width = self.frame.width
let height = self.frame.height
let labelOffset: CGFloat = 5

let attributes = labelAttributes(alignment: .center, foregroundColor: color.mouseNumber)

let mouseNumber = self.getMouseNumberLabel(number)
let label = NSAttributedString(string: mouseNumber, attributes: attributes)
let labelSize = label.size()

let rightPosition = number + labelOffset;
let leftPosition = number - labelOffset - labelSize.width
let enoughRoomToTheRight = rightPosition + labelSize.width < width - labelOffset
let labelX = enoughRoomToTheRight ? rightPosition : leftPosition

let labelRect = CGRect(x: labelX, y: height - labelSize.height, width: labelSize.width, height: labelSize.height)
let labelRect = mouseNumberLabelRect(
number: number,
labelSize: labelSize,
rulerSize: CGSize(width: width, height: height)
)

label.draw(
with: labelRect,
context: nil
)
}

func mouseNumberLabelRect(number: CGFloat, labelSize: CGSize, rulerSize: CGSize) -> CGRect {
let labelOffset: CGFloat = 5

let rightPosition = number + labelOffset
let leftPosition = number - labelOffset - labelSize.width
var maxLabelRight = rulerSize.width - labelOffset

if let resizeHandleExclusionFrame = resizeHandleExclusionFrame {
maxLabelRight = min(
maxLabelRight,
resizeHandleExclusionFrame.minX - mouseTickLabelResizeHandleSpacing
)
}

let pinnedRightPosition = maxLabelRight - labelSize.width
let rightLabelX = min(rightPosition, pinnedRightPosition)
let leftLabelX = min(leftPosition, pinnedRightPosition)
let labelX = number < rightLabelX ? rightLabelX : leftLabelX

return CGRect(
x: labelX,
y: rulerSize.height - labelSize.height,
width: labelSize.width,
height: labelSize.height
)
}

func drawUnitLabel() {
let attributes = labelAttributes(alignment: .left, foregroundColor: color.ticks)

Expand Down
2 changes: 1 addition & 1 deletion Free Ruler/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -758,5 +758,5 @@
}
}
},
"version" : "1.0"
"version" : "1.1"
}
2 changes: 1 addition & 1 deletion Free Ruler/ResizeHandleView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ private struct ResizeHandleCursorPreview: View {
)
} else {
VStack(spacing: 0) {
Text("Unavailable")
Text(verbatim: "Unavailable")
.font(.caption.monospaced())
.frame(width: 130, height: 80)
.background(Color(red: 0.25, green: 0.49, blue: 0.46))
Expand Down
5 changes: 5 additions & 0 deletions Free Ruler/RuleView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ struct RulerColors {
class RuleView: NSView {

let color = RulerColors()
let mouseTickLabelResizeHandleSpacing: CGFloat = 8
private var resizeHandleView: ResizeHandleView?

var trackingArea: NSTrackingArea?
Expand Down Expand Up @@ -111,6 +112,10 @@ class RuleView: NSView {
prefs.unit
}

var resizeHandleExclusionFrame: NSRect? {
return resizeHandleView?.frame
}

func getUnitLabel() -> String {
switch unit {
case .pixels:
Expand Down
27 changes: 19 additions & 8 deletions Free Ruler/VerticalRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,21 +115,14 @@ class VerticalRule: RuleView {
func drawMouseNumber(_ mouseTickY: CGFloat) {
let height = self.frame.height
let number = height - mouseTickY
let labelOffset: CGFloat = 2

let attributes = labelAttributes(alignment: .left, foregroundColor: color.mouseNumber)

let mouseNumber = self.getMouseNumberLabel(number)
let label = NSAttributedString(string: mouseNumber, attributes: attributes)
let labelSize = label.size()

// manually offsetting bottom position til i can figure out how to center text vertically in the label rect
let bottomPosition = number + 7;
let topPosition = number - labelOffset - labelSize.height
let enoughRoomToTheBottom = bottomPosition + labelSize.height < height - labelOffset
let labelY = enoughRoomToTheBottom ? bottomPosition : topPosition

let labelRect = CGRect(x: 7, y: height - (labelY + labelSize.height), width: 22, height: 15)
let labelRect = mouseNumberLabelRect(number: number, labelSize: labelSize, rulerHeight: height)
color.fill.setFill()
labelRect.fill()

Expand All @@ -140,6 +133,24 @@ class VerticalRule: RuleView {
)
}

func mouseNumberLabelRect(number: CGFloat, labelSize: CGSize, rulerHeight: CGFloat) -> CGRect {
let labelOffset: CGFloat = 2

// manually offsetting bottom position til i can figure out how to center text vertically in the label rect
let bottomPosition = number + 7
let topPosition = number - labelOffset - labelSize.height
let enoughRoomToTheBottom = bottomPosition + labelSize.height < rulerHeight - labelOffset
let labelY = enoughRoomToTheBottom ? bottomPosition : topPosition
var labelRect = CGRect(x: 7, y: rulerHeight - (labelY + labelSize.height), width: 22, height: 15)

if let resizeHandleExclusionFrame = resizeHandleExclusionFrame {
let minLabelBottom = resizeHandleExclusionFrame.maxY + mouseTickLabelResizeHandleSpacing
labelRect.origin.y = max(labelRect.origin.y, minLabelBottom)
}

return labelRect
}

func drawUnitLabel() {
let attributes = labelAttributes(alignment: .left, foregroundColor: color.ticks)

Expand Down
69 changes: 69 additions & 0 deletions FreeRulerTests/RulerCoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,75 @@ final class RulerCoreTests: XCTestCase {
XCTAssertFalse(verticalCursor.image.isTemplate)
}

func testHorizontalMouseTickLabelStopsBeforeResizeHandle() {
let rule = HorizontalRule(frame: NSRect(x: 0, y: 0, width: 300, height: Ruler.thickness))
guard let resizeHandleFrame = rule.resizeHandleExclusionFrame else {
return XCTFail("Expected horizontal ruler to install a resize handle")
}
let labelSize = CGSize(width: 30, height: 10)
let rulerSize = rule.bounds.size
let expectedMaxLabelRight = resizeHandleFrame.minX - rule.mouseTickLabelResizeHandleSpacing
let pinnedLabelX = expectedMaxLabelRight - labelSize.width
let mouseTickBeforePinnedLabel = pinnedLabelX - 2

let labelRect = rule.mouseNumberLabelRect(
number: mouseTickBeforePinnedLabel,
labelSize: labelSize,
rulerSize: rulerSize
)

XCTAssertGreaterThan(labelRect.minX, mouseTickBeforePinnedLabel)
XCTAssertEqual(
labelRect.maxX,
expectedMaxLabelRight,
accuracy: 0.0001
)
}

func testHorizontalMouseTickLabelFlipsBeforeCollidingWithMouseTick() {
let rule = HorizontalRule(frame: NSRect(x: 0, y: 0, width: 300, height: Ruler.thickness))
guard let resizeHandleFrame = rule.resizeHandleExclusionFrame else {
return XCTFail("Expected horizontal ruler to install a resize handle")
}
let labelSize = CGSize(width: 30, height: 10)
let rulerSize = rule.bounds.size
let expectedMaxLabelRight = resizeHandleFrame.minX - rule.mouseTickLabelResizeHandleSpacing
let mouseTickInsideResizeHandle = resizeHandleFrame.minX + 1

let labelRect = rule.mouseNumberLabelRect(
number: mouseTickInsideResizeHandle,
labelSize: labelSize,
rulerSize: rulerSize
)

XCTAssertGreaterThan(mouseTickInsideResizeHandle, resizeHandleFrame.minX)
XCTAssertLessThan(labelRect.maxX, mouseTickInsideResizeHandle)
XCTAssertEqual(
labelRect.maxX,
expectedMaxLabelRight,
accuracy: 0.0001
)
}
Comment thread
pascalpp marked this conversation as resolved.

func testVerticalMouseTickLabelStopsBeforeResizeHandle() {
let rule = VerticalRule(frame: NSRect(x: 0, y: 0, width: Ruler.thickness, height: 300))
guard let resizeHandleFrame = rule.resizeHandleExclusionFrame else {
return XCTFail("Expected vertical ruler to install a resize handle")
}

let labelRect = rule.mouseNumberLabelRect(
number: 290,
labelSize: CGSize(width: 22, height: 10),
rulerHeight: 300
)

XCTAssertEqual(
labelRect.minY,
resizeHandleFrame.maxY + rule.mouseTickLabelResizeHandleSpacing,
accuracy: 0.0001
)
}

func testResizeHandleDisablesWindowBackgroundDraggingDuringResizeDrag() {
let ruler = Ruler(.horizontal, frame: NSRect(x: 0, y: 0, width: 300, height: Ruler.thickness))
let window = RulerWindow(ruler)
Expand Down