Commit a6288f9
authored
Make rulers flippable (#199)
* stubbed out Flip menu
* Address flip ruler PR comments
* Localize flip submenu titles
* Restore zero corner test defaults domain
* Add defaultZeroCorner and use in prefs
Introduce Prefs.defaultZeroCorner and use it as the canonical default for zeroCorner. Update the prefs defaults dictionary and the zeroCorner(fromRawValue:) fallback to reference defaultZeroCorner. Ensure resetRulerPositions restores zeroCorner to the canonical default. Add a unit test to assert the default is .topLeft.
* Address PR feedback on flip shortcuts and defaults
* Use default zero corner in UI test reset
* Introduce zero corner geometry helpers
* Align left resize handle inset
* Preserve screen origin for default rulers
* Update ruler drawing for zero corners
* Mirror unit label mouse tick gating
* Revert "Mirror unit label mouse tick gating"
This reverts commit 728a4b0.
* Cover direction-aware resizing
* Handle grouped zero-corner flips
* Wire and guard grouped ruler flips
* Add flip ruler UI
* Verify flippable ruler integration
* Derive flipped label test scale from screen
* Ignore Caps Lock for ruler hotkeys
* Address flip ruler review comments
* Anchor labels/handles to opposite sides and update tests
Add RulerSide.opposite and update label/handle geometry to anchor unit labels and resize handles relative to the far/opposite corner derived from ZeroCornerGeometry. HorizontalRule and VerticalRule now compute label X/Y anchors using geometry.opposite sides (and use a fixed textHeight for top labels). ResizeHandleView uses tickSide.opposite to place vertical/horizontal handles correctly. Update RulerCoreTests: adjust expected rects, add a unit-label positioning test, rename/expand resize-handle assertions to check X and Y anchoring, and wrap tests to set/restore zeroCorner preference where needed.
* Encapsulate resize-handle placement logic
Add RulerCornerPlacement and a new ZeroCornerGeometry.resizeHandlePlacement(for:) helper to compute the x/y sides for resize handles based on orientation and zero corner. Refactor ResizeHandleView to use placement.xSide/placement.ySide instead of separately computing tickSide, resizeSide and their opposites, simplifying control flow and removing duplicated logic. Changes in Ruler.swift and ResizeHandleView.swift; no intended behavioral change.
* Add UnitLabelView and integrate unit labels
Introduce UnitLabelView to centralize unit label sizing, framing and drawing. Move unit label placement logic into UnitLabelView.labelFrame and ZeroCornerGeometry.unitLabelPlacement, and wire a unitLabelView subview into RuleView with install/update methods. HorizontalRule and VerticalRule now install the subview and override visibility logic to hide the label when the mouse tick overlaps it. Update project file to include the new source and adjust/extend unit tests to match the new layout behavior and verify subview positioning and baseline consistency.
* Simplify unit label positioning and add insets
Replace the orientation-heavy coordinate logic with a simpler corner-based switch and explicit insets. Introduces top/bottom/left/right inset constants and computes x/y from placement.xSide and placement.ySide (four corner cases), removes redundant orientation branches, and consolidates the assertion/fallback behavior.
* Adjust unit label insets and update tests
Tweak UnitLabelView insets (bottom: 10→9, left/right: 7→8) to correct unit label positioning. Update RulerCoreTests expected CGRects to match the adjusted layout. Files changed: Free Ruler/UnitLabelView.swift and FreeRulerTests/RulerCoreTests.swift.
* Refactor mouse tick layout & handle visibility
Introduce MouseTickLabelLayout to centralize mouse-tick label placement logic for both horizontal and vertical rulers, replacing per-rule mouseNumberLabelRect implementations. Add resize-handle obscuring support via setResizeHandleObscured and per-rule updateResizeHandleVisibility overrides so the resize handle fades when a mouse tick overlaps it; wire visibility updates into layout/preference changes and mouse-tick/showMouseTick setters. Update tests to reflect the new layout API and visual-obscuring behavior and remove the older mouseTickLabelResizeHandleSpacing constant.
* Add mouse tick label preview views
Introduce debug-only preview tooling to visualize mouse tick label layout and offsets. Adds MouseTickLabelLayoutPreview (NSViewRepresentable) and MouseTickLabelLayoutPreviewView to draw ruler ticks, mouse tick line/label, unit label, and resize handle; plus SwiftUI helpers MouseTickLabelOffsetPreview and MouseTickLabelCornerPreview to show combinations of zero corners and orientations. Update RuleView_Previews to group horizontal/vertical ruler previews and include the new Mouse Tick Labels preview.
* Propagate zeroCorner and refactor previews
Replace direct prefs.zeroCorner usages with a RuleView.zeroCorner property and propagate that value to child views (UnitLabelView, ResizeHandleView, HorizontalRule, VerticalRule). Add frame(in:bounds, zeroCorner:) overloads and update layout code to use the passed zeroCorner. Introduce RuleView.installWindowBorder() and improve window size fallbacks. Add nil-checks for NSGraphicsContext before drawing label rectangles. Refactor DEBUG preview code: replace the old MouseTickLabelLayoutPreview with a compact MouseTickRulePreview that hosts new MouseTickPreviewHorizontalRule/VerticalRule subclasses, and wire preview configuration (previewZeroCorner, mouse positions, colors). Also add a new localized string key to Localizable.xcstrings.
* Remove RuleViewPreview and simplify previews
Delete the NSViewRepresentable RuleViewPreview and the HStack of horizontal/vertical rule previews. Replace the previous preview group with a single MouseTickLabelOffsetPreview and adjust the preview layout/name. This simplifies SwiftUI previews by removing the AppKit bridging preview helper and duplicate preview entries.
* Update Free Ruler help screen
* Use current app icon in help book
* Update help icon when generating app icons
* Stabilize Free Ruler help book caching
* Use timestamped help icon filenames
Switch help icon naming from a build-number-based token to a UTC timestamp+hash token. Update FreeRuler HTML and CSS to reference the new freeruler-help-icon-<timestamp>-<hash>.png name, rename the icon file accordingly, and remove the old freeruler.png legacy copy. Update scripts/generate-app-icon.sh to generate a timestamped help_cache_token, drop the Info.plist build_number dependency, remove legacy copy behavior, and propagate the new token into styles.css and FreeRuler.html while cleaning up stale icons.
* Use CSS var for help icon and refresh assets
Introduce a CSS variable for the help icon and refresh related assets.
- FreeRuler.html: add :root style setting --free-ruler-help-icon, update styles.css query token, tidy metadata and reformat the keyboard shortcuts/feature sections.
- styles.css: switch .title-page-header background-image to use var(--free-ruler-help-icon).
- Replace old help icon with a new freeruler-help-icon PNG and remove the old file.
- Update multiple AppIcon image assets (various sizes) — regenerated icons.
- scripts/generate-app-icon.sh: combine perl substitutions to inject the cache token and set the --free-ruler-help-icon URL in the HTML, and remove an unused variable.
These changes allow the help page to reference the generated icon dynamically and support cache-busting when regenerating icons.
* Update project.pbxproj
* Update project.pbxproj
* Add help-index generator and npm script
Add scripts/generate-help-index.sh which runs hiutil to build English.lproj.helpindex from Free Ruler/FreeRuler.help/Contents/Resources/English.lproj (script uses strict bash flags and executes from repo root). Wire the script into package.json as the "generate:help" npm script and update the packaged help index file accordingly so the help index can be regenerated as part of build tasks.
* Fix help bundle identifier & version handling
Use a fixed help bundle identifier and stop appending the build number. Updated FreeRuler.help/Contents/Info.plist to set CFBundleIdentifier to com.pascal.freeruler.help and adjusted CFBundleVersion to 491. Replaced the templated CFBundleHelpBookName in Free Ruler/Info.github.plist and Free Ruler/Info.plist with the fixed help ID. Removed the code in scripts/release/set-version.js that modified the help CFBundleIdentifier per-build so the help bundle ID remains stable across builds.
* Update set-version.js
* revert help menu handler
* Update bump-version.js
* Update generate-app-icon.sh
* Add interactive mouse tick label preview UI
Introduce an adjustable preview for mouse tick label offsets used in DEBUG builds. Adds a mouseTickLabelPreviewRulerLength constant and refactors MouseTickLabelOffsetPreview into smaller views: heading, grid, controls, slider panel, and individual sliders with a numeric TextField (clamped and rounded). Replaces hardcoded 260 ruler length usage, extracts a cornerPreview helper, and updates the PreviewProvider to use the interactive controls for easier testing of label offsets.
* Centralize resize handle end-region check
Introduce RuleView.resizeHandleEndRegionContains(...) to encapsulate logic that determines whether the mouse tick overlaps the resize-handle end region based on ruler orientation and the current zeroCorner/resize side. Replace the inline min/max checks in HorizontalRule and VerticalRule with calls to this helper. Expand and rename unit tests to cover obscuring behavior from the leading edge to the ruler end across different zeroCorner configurations. Includes an assertionFailure fallback for unexpected cases.
* Avoid mouse tick label overlapping resize handle
Prevent mouse-tick/unit labels from overlapping the ruler resize handle and from incorrectly hiding near the zero edge. MouseTickLabelLayout now accepts an optional resizeHandleFrame and tickGap was renamed to tickLabelSpacing; layout logic was extended with horizontal/vertical helper checks to prefer the side that doesn't collide with the resize handle. RuleView gained unitLabelZeroRegionContains and HorizontalRule/VerticalRule use it to compute unit-label visibility based on growth direction and bounds. Debug previews and sliders were adjusted to exercise the new behavior, and unit tests were added to cover zero-edge hiding and label flipping around the resize handle.
* Propagate zeroCorner and refactor geometry
Pass zeroCorner into child views and clean up geometry/layout logic. ResizeHandleView now computes grip and slot frames (gripRect/gripSize/slotFrame) and draws grip/bg relative to the grip; it accepts a zeroCorner override. UnitLabelView gets explicit padding, safer draw rect to leave room for descenders, and accepts zeroCorner for placement. MouseTickLabelLayout was extended to handle unitLabelFrame, vertical lanes, and revised offsets; added labelBackgroundFrame helper. HorizontalRule/VerticalRule use growthDirection-aware mouse tick line helpers and simplified unit label / resize-handle visibility checks. Tests updated and new unit tests added to cover the new layout behavior and zeroCorner override.
* tweak mouse tick layout and update tests
* Address PR feedback on ruler labels and help assets
* Continue resize handle placement assertions
* Update English.lproj.helpindex
* Reset group setting to default in resetRulerPositions
* Reset Ruler Positions → Reset Rulers
* Add flip rulers screenshot layout
Adds the flip rulers App Store screenshot in output position 3, removes Screen prefixes from preview labels, splits screenshot constants by layout, and models the flip rulers with corner-relative inset positioning, grouped copy placement, and distinct non-yellow colors.
* Update AppStoreScreenshotPreview.swift
* Update AppStoreScreenshotPreview.swift
* update screenshots1 parent 13c5c53 commit a6288f9
52 files changed
Lines changed: 4488 additions & 762 deletions
File tree
- Free Ruler.xcodeproj
- Free Ruler
- Base.lproj
- FreeRuler.help/Contents
- Resources
- English.lproj
- shrd
- Images.xcassets/AppIcon.appiconset
- de.lproj
- es.lproj
- fi.lproj
- ja.lproj
- zh-hans.lproj
- FreeRulerTests
- appstore/screenshots
- scripts
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
35 | | - | |
36 | 35 | | |
| 36 | + | |
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
| 42 | + | |
| 43 | + | |
42 | 44 | | |
43 | 45 | | |
44 | 46 | | |
| |||
118 | 120 | | |
119 | 121 | | |
120 | 122 | | |
| 123 | + | |
121 | 124 | | |
122 | 125 | | |
123 | 126 | | |
| |||
139 | 142 | | |
140 | 143 | | |
141 | 144 | | |
142 | | - | |
| 145 | + | |
143 | 146 | | |
144 | 147 | | |
145 | 148 | | |
| |||
252 | 255 | | |
253 | 256 | | |
254 | 257 | | |
| 258 | + | |
255 | 259 | | |
256 | 260 | | |
257 | 261 | | |
| |||
479 | 483 | | |
480 | 484 | | |
481 | 485 | | |
| 486 | + | |
482 | 487 | | |
483 | 488 | | |
484 | 489 | | |
| |||
504 | 509 | | |
505 | 510 | | |
506 | 511 | | |
| 512 | + | |
507 | 513 | | |
508 | 514 | | |
509 | 515 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
37 | 43 | | |
38 | 44 | | |
39 | 45 | | |
| |||
57 | 63 | | |
58 | 64 | | |
59 | 65 | | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
60 | 78 | | |
61 | 79 | | |
62 | 80 | | |
| |||
127 | 145 | | |
128 | 146 | | |
129 | 147 | | |
130 | | - | |
131 | 148 | | |
132 | 149 | | |
133 | 150 | | |
| |||
218 | 235 | | |
219 | 236 | | |
220 | 237 | | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
221 | 241 | | |
222 | 242 | | |
223 | 243 | | |
| |||
262 | 282 | | |
263 | 283 | | |
264 | 284 | | |
| 285 | + | |
265 | 286 | | |
266 | 287 | | |
267 | 288 | | |
| |||
274 | 295 | | |
275 | 296 | | |
276 | 297 | | |
| 298 | + | |
277 | 299 | | |
278 | 300 | | |
279 | 301 | | |
| |||
479 | 501 | | |
480 | 502 | | |
481 | 503 | | |
| 504 | + | |
| 505 | + | |
482 | 506 | | |
483 | | - | |
484 | 507 | | |
485 | 508 | | |
486 | 509 | | |
487 | 510 | | |
488 | 511 | | |
489 | | - | |
490 | | - | |
| 512 | + | |
| 513 | + | |
491 | 514 | | |
492 | 515 | | |
493 | 516 | | |
| |||
503 | 526 | | |
504 | 527 | | |
505 | 528 | | |
506 | | - | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
507 | 631 | | |
508 | 632 | | |
509 | 633 | | |
| |||
538 | 662 | | |
539 | 663 | | |
540 | 664 | | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
541 | 699 | | |
542 | 700 | | |
543 | 701 | | |
| |||
0 commit comments