-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add laissez vibrer ties #25435
base: master
Are you sure you want to change the base?
Add laissez vibrer ties #25435
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty nice. Thank you so much. One comment on my side for the MusicXML export.
NB: the export to MEI also has to be adjusted. I can do that, if you like.
const Tie* tieFor = note->tieFor(); | ||
if (tieFor && ExportMusicXml::canWrite(tieFor)) { | ||
if (tieFor && !laissezVib && ExportMusicXml::canWrite(tieFor)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This way all styling of lv ties gets lost. Better to adjust the previous clause to just exchange type="start"
with type="let-ring"
.
Another thing that I noticed during testing: lv styles are not being saved, so direction, color and line styles are lost. |
Should l.v. ties get a tie placement style option too? |
@XiaoMigros They follow that of normal ties, which can also be overridden in Properties. |
80b7faa
to
014794c
Compare
@rettinghaus I'd be really grateful if you could take a look at the MEI side of things when this is merged! |
Really loving this PR @miiizen! Just one nit-picky UI point: We should use the label "Laissez vibrer" in these places, instead of "Laissez vib" |
Add laisser vib class Add styles Add lv layout methods Create smufl symbol layout Refactor laisser vib to be a child of Tie Add MuseScore tie layout Create properties panel for lv ties Add style settings Add icons and input toolbar button Fix layout & file reading/writing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outstanding work!
src/engraving/dom/laissezvib.cpp
Outdated
initElementStyle(&laissezVibStyle); | ||
} | ||
|
||
mu::engraving::PropertyValue mu::engraving::LaissezVib::getProperty(Pid propertyId) const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mu::engraving shouldn't be necessary here, as you have the using namespace
statement above. Actually, I think all of this should be done inside the engraving namespace . Meaning that instead of having the using namespace you'd just open namespace mu::engraving { ... }
and put all your code inside it (that's how we do it for all the other items if I'm not mistaken).
src/engraving/dom/laissezvib.cpp
Outdated
return up() ? SymId::articLaissezVibrerAbove : SymId::articLaissezVibrerBelow; | ||
} | ||
|
||
static int compareNotesPos(const Note* n1, const Note* n2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a function that I can see being useful in many other contexts. In fact, I suspect that there may be something similar to this already, I can definitely remember having to use similar logic before, but I may be wrong. In any case, a better place for this could be in the utils
file.
src/engraving/dom/laissezvib.cpp
Outdated
} | ||
} | ||
|
||
void LaissezVib::calculateDirection() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of thoughts (referred to all three of these functions, namely calculateDirection, calculateIsInside, isOuterTieOfChord).
- I wonder if it would be worth trying to factor out some of the reused code here. I can see that the logic is quite similar to normal ties, with the obvious difference that we aren't looking at the end chord. The answer may well be no: sometimes avoiding repetitions at all costs can result in messier code. But do give it a thought, if you can see any easy way of doing it. A pattern that I've found useful sometimes when dealing with overrides like this is to separate the part that's common from the part that's overridden (see for instance Spanner::computeEndElement and Spanner::doComputeEndElement to see what I mean).
- Independently from the previous point: perhaps calculateDirection, which is the more strictly layout-dependend one, is worth moving out of the DOM and into the layout module?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and the point above became immediately obvious when beginning partial ties! I'll tidy these up and just have single methods in Tie
which handle both start & end or only one or the other.
src/engraving/dom/spanner.h
Outdated
@@ -220,31 +220,31 @@ class Spanner : public EngravingItem | |||
void setNoteSpan(Note* startNote, Note* endNote); | |||
|
|||
EngravingItem* startElement() const { return m_startElement; } | |||
EngravingItem* endElement() const { return m_endElement; } | |||
virtual EngravingItem* endElement() const { return m_endElement; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to override all of these methods? Does it become too annoying if you just ensure that m_endElement is always null for LV ties and let the other methods (which work with m_endElement) deal with it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought this was pretty ugly, glad to get rid of it. It does work when only overriding setEndNote
and setEndElement
to which I've added a stronger assertion.
@@ -1350,48 +1351,6 @@ void SlurTieLayout::avoidPreBendsOnTab(const Chord* sc, const Chord* ec, SlurTie | |||
} | |||
} | |||
|
|||
TieSegment* SlurTieLayout::layoutTieWithNoEndNote(Tie* item) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
THANK YOU, I couldn't wait to get rid of this horror
@@ -19,12 +19,13 @@ | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <https://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef MU_ENGRAVING_SLURTIELAYOUT_DEV_H | |||
#define MU_ENGRAVING_SLURTIELAYOUT_DEV_H | |||
#pragma once |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing bad about this, but since we use the #ifndef / #endif for every other header file in our repo, I'd rather keep it consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is changing; we're now gradually switching to #pragma once
everywhere. New files should use #pragma once
, and existing files could/should be updated when they are touched anyway.
Resolves: #16726
This PR adds laissez vibrer ties. They are added via a toggle in the toolbar.
Screen.Recording.2024-11-05.at.15.03.42.mov
Laissez vib ties are drawn as normal ties, with all the same style options plus a minimum length available in the properties panel.
Screen.Recording.2024-11-05.at.15.04.51.mov
When multiple LV ties are added to a chord, the 'minimum length' for whichever tie starts furthest to the right is honoured, and then the right endpoints of all the other ties are extended to match.
Screen.Recording.2024-11-05.at.15.07.21.mov
There is also the option to use SMuFL symbols instead of MuseScore's own ties. When added to a chord, these will all end at the rightmost point any tie reaches and will start at the same point as their length is not variable.
Properties:
Style settings:
This element is implemented as a child of the
Tie
class which makes it aSpanner
without an end element. The relevant methods have been overriden to enforce this. The spanner will also only ever have a single segment.In old scores, laissez vibrer articulations will be converted to the new ties.