Add breath mark ornament - #33
Merged
Merged
Conversation
Adds OrnamentType.BreathMark, wired through the same ribbon/Edit-menu/ context-menu pattern as the existing ornaments (Grace/Trill/Turn/ Mordent/Fermata). Unlike those, a breath mark is anchored just after the note's right edge instead of centered above it, since that's where it's placed in notasi angka/jianpu sheet music -- one new branch each in JianpuRenderer.GetOrnamentAnchorX (non-compact layout) and NoteTopAnnotationLayout.GetOrnamentAnchorX (compact/stacked layout). It reuses the existing ornament Y-band and doesn't touch accidental/octave-dot collision math, so it carries none of the layout risk flagged in ROADMAP.md for the accidental slash-convention work. Visual-only: no playback or MIDI-export effect. While scoping the roadmap's next item (a natural/pugar accidental sign), found that AccidentalKind.Sharp/Flat have no manual entry UI anywhere in the app -- accidentals are currently only ever produced by MIDI import. Documented this in ROADMAP.md as a prerequisite gap rather than shipping a natural-sign glyph nothing could attach, and picked breath marks (independently scoped, no prerequisite) instead. Verified via the same sandbox pipeline as every prior change this session: dotnet build succeeds against the real project/package graph, dotnet format --verify-no-changes passes on both projects, and new xUnit tests cover the placeholder glyph and the anchor-position branch. dotnet test itself cannot execute in this sandbox (no WindowsDesktop runtime pack); real confirmation comes from GitHub Actions CI. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pguj4XSScE141p1ScWoqEr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Continuing the Indonesian notasi angka gap list (
ROADMAP.md), next low-risk item.OrnamentType.BreathMark), wired through the same ribbon +Edit-menu + context-menu pattern as the existing ornaments (Grace/Trill/Turn/Mordent/Fermata).
Unlike those, a breath mark is anchored just after the note's right edge instead of centered
above it, matching where it's actually placed in notasi angka/jianpu sheet music -- one new
branch each in
JianpuRenderer.GetOrnamentAnchorX(non-compact layout) andNoteTopAnnotationLayout.GetOrnamentAnchorX(compact/stacked layout used by the editor and PDFexport). It reuses the existing ornament Y-band and doesn't touch the accidental/octave-dot
collision math at all, so it doesn't carry the layout risk flagged in
ROADMAP.mdfor theaccidental slash-convention work. Visual-only: no playback or MIDI-export effect (matching the
roadmap's stated v1 scope).
While scoping the roadmap's originally-next item (a natural/pugar accidental sign,
♮), found areal prerequisite gap:
AccidentalKind.Sharp/Flathave no manual entry UI anywhere in theapp --
JianpuPitchCodec.SetAccidentalPitchis never called outside its own tests, and the onlycode path that ever produces an accidental note is
MidiImportServicereading a chromatic pitchout of an imported file. Shipping a natural-sign glyph would be dead weight without that entry
point first, so documented this in
ROADMAP.mdas a real prerequisite and picked breath marksinstead, which needed no such prerequisite.
Test plan
Verified via the same sandbox pipeline as every prior change this session:
dotnet buildsucceeds against the real project/package graph (0 errors/warnings).dotnet format --verify-no-changespasses on both projects.OrnamentService.GetPlaceholderGlyph(BreathMark), the new anchor-positionbranch in
NoteTopAnnotationLayout.GetOrnamentAnchorX, and a render-to-bitmap smoke test in bothcompact and default layout modes.
Not verified in this sandbox: the breath mark's actual on-screen appearance/position hasn't
been visually confirmed on a real Windows machine, same caveat as every prior UI change this
session.
dotnet testitself cannot execute here (no WindowsDesktop runtime pack); realconfirmation of the new tests comes from GitHub Actions CI.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Pguj4XSScE141p1ScWoqEr
Generated by Claude Code