Skip to content
Draft
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
37 changes: 7 additions & 30 deletions src/engraving/dom/chord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "articulation.h"
#include "beam.h"
#include "chordline.h"
#include "dom/parenthesis.h"
#include "drumset.h"
#include "factory.h"
#include "guitarbend.h"
Expand Down Expand Up @@ -64,6 +65,7 @@
#include "tremolotwochord.h"
#include "trill.h"
#include "tuplet.h"
#include "utils.h"

#ifndef ENGRAVING_NO_ACCESSIBILITY
#include "accessibility/accessibleitem.h"
Expand Down Expand Up @@ -1252,6 +1254,11 @@ void Chord::scanElements(std::function<void(EngravingItem*)> func)
for (EngravingItem* e : el()) {
e->scanElements(func);
}

for (auto& p : m_noteParens) {
p.first.first->scanElements(func);
p.first.second->scanElements(func);
}
ChordRest::scanElements(func);
}

Expand Down Expand Up @@ -2106,36 +2113,6 @@ void Chord::requestShowStemSlash(bool show)
// sortNotes
//---------------------------------------------------------

static bool noteIsBefore(const Note* n1, const Note* n2)
{
const int l1 = n1->line();
const int l2 = n2->line();
if (l1 != l2) {
return l1 > l2;
}

const int p1 = n1->pitch();
const int p2 = n2->pitch();
if (p1 != p2) {
return p1 < p2;
}

if (n1->tieBack()) {
if (n2->tieBack() && !n2->incomingPartialTie()) {
const Note* sn1 = n1->tieBack()->startNote();
const Note* sn2 = n2->tieBack()->startNote();
if (sn1->chord() == sn2->chord()) {
return sn1->unisonIndex() < sn2->unisonIndex();
}
return sn1->chord()->isBefore(sn2->chord());
} else {
return true; // place tied notes before
}
}

return false;
}

void Chord::sortNotes()
{
std::sort(notes().begin(), notes().end(), noteIsBefore);
Expand Down
7 changes: 7 additions & 0 deletions src/engraving/dom/chord.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ class GraceNotesGroup final : public std::vector<Chord*>, public EngravingItem
// @P stemDirection Direction the stem direction of the chord: AUTO, UP, DOWN (read only)
//---------------------------------------------------------

using ParenthesisPair = std::pair<Parenthesis*, Parenthesis*>;
using NoteParenthesisInfo = std::map<ParenthesisPair, std::vector<Note*> >;

class Chord final : public ChordRest
{
OBJECT_ALLOCATOR(engraving, Chord)
Expand Down Expand Up @@ -159,6 +162,9 @@ class Chord final : public ChordRest
std::vector<Note*>& notes() { return m_notes; }
const std::vector<Note*>& notes() const { return m_notes; }

const NoteParenthesisInfo& noteParens() const { return m_noteParens; }
NoteParenthesisInfo& noteParens() { return m_noteParens; }

bool isChordPlayable() const;
void setIsChordPlayable(const bool isPlayable);

Expand Down Expand Up @@ -368,6 +374,7 @@ class Chord final : public ChordRest

std::vector<Note*> m_notes; // sorted to decreasing line step
std::vector<LedgerLine*> m_ledgerLines;
NoteParenthesisInfo m_noteParens;

Stem* m_stem = nullptr;
Hook* m_hook = nullptr;
Expand Down
11 changes: 9 additions & 2 deletions src/engraving/dom/chordrest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ void ChordRest::add(EngravingItem* e)
e->added();
break;
default:
ASSERT_X(u"ChordRest::add: unknown element " + String::fromAscii(e->typeName()));
EngravingItem::add(e);
break;
}
}
Expand All @@ -597,7 +597,7 @@ void ChordRest::remove(EngravingItem* e)
}
break;
default:
ASSERT_X(u"ChordRest::remove: unknown element " + String::fromAscii(e->typeName()));
EngravingItem::remove(e);
}
}

Expand Down Expand Up @@ -1057,6 +1057,13 @@ void ChordRest::scanElements(std::function<void(EngravingItem*)> func)
if (m_tabDur) {
func(m_tabDur);
}

if (leftParen()) {
func(leftParen());
}
if (rightParen()) {
func(rightParen());
}
}

//---------------------------------------------------------
Expand Down
7 changes: 6 additions & 1 deletion src/engraving/dom/note.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2941,6 +2941,8 @@ PropertyValue Note::getProperty(Pid propertyId) const
return fixed();
case Pid::FIXED_LINE:
return fixedLine();
case Pid::HAS_PARENTHESES:
return m_hasParens ? ParenthesesMode::BOTH : ParenthesesMode::NONE;
case Pid::POSITION_LINKED_TO_MASTER:
case Pid::APPEARANCE_LINKED_TO_MASTER:
if (chord()) {
Expand Down Expand Up @@ -3048,7 +3050,10 @@ bool Note::setProperty(Pid propertyId, const PropertyValue& v)
setFixedLine(v.toInt());
break;
case Pid::HAS_PARENTHESES:
setParenthesesMode(v.value<ParenthesesMode>());
if (v.value<ParenthesesMode>() != ParenthesesMode::BOTH && v.value<ParenthesesMode>() != ParenthesesMode::NONE) {
ASSERT_X("Notes cannot set left & right parens individually");
}
m_hasParens = v.value<ParenthesesMode>() == ParenthesesMode::BOTH;
if (links()) {
for (EngravingObject* scoreElement : *links()) {
Note* note = toNote(scoreElement);
Expand Down
2 changes: 2 additions & 0 deletions src/engraving/dom/note.h
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,8 @@ class Note final : public EngravingItem

bool m_harmonic = false;

bool m_hasParens = false;

ElementList m_el; // fingering, other text, symbols or images
std::vector<NoteDot*> m_dots;
NoteEventList m_playEvents;
Expand Down
30 changes: 30 additions & 0 deletions src/engraving/dom/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1847,4 +1847,34 @@ std::vector<EngravingItem*> filterTargetElements(const Selection& sel, Engraving
}
return result;
}

bool noteIsBefore(const Note* n1, const Note* n2)
{
const int l1 = n1->line();
const int l2 = n2->line();
if (l1 != l2) {
return l1 > l2;
}

const int p1 = n1->pitch();
const int p2 = n2->pitch();
if (p1 != p2) {
return p1 < p2;
}

if (n1->tieBack()) {
if (n2->tieBack() && !n2->incomingPartialTie()) {
const Note* sn1 = n1->tieBack()->startNote();
const Note* sn2 = n2->tieBack()->startNote();
if (sn1->chord() == sn2->chord()) {
return sn1->unisonIndex() < sn2->unisonIndex();
}
return sn1->chord()->isBefore(sn2->chord());
} else {
return true; // place tied notes before
}
}

return false;
}
}
2 changes: 2 additions & 0 deletions src/engraving/dom/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,6 @@ extern bool isValidBarLineForRepeatSection(const Segment* firstSeg, const Segmen
extern bool isElementInFretBox(const EngravingItem* item);

extern std::vector<EngravingItem*> filterTargetElements(const Selection& sel, EngravingItem* dropElement, bool& unique);

extern bool noteIsBefore(const Note* n1, const Note* n2);
} // namespace mu::engraving
24 changes: 24 additions & 0 deletions src/engraving/editing/cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3395,6 +3395,26 @@ void Score::cmdAddBracket()

void Score::cmdAddParentheses()
{
std::list<Note*> notes = selection().uniqueNotes();
if (!notes.empty()) {
std::map<Chord*, std::vector<Note*> > notesByChord;
for (Note* note : notes) {
Chord* chord = note->chord();
auto it = notesByChord.find(chord);
if (it != notesByChord.end()) {
it->second.push_back(note);
} else {
std::vector<Note*> noteVector{ note };
notesByChord.insert(std::make_pair(chord, noteVector));
}
}

for (auto& i : notesByChord) {
Chord* chord = i.first;
EditChord::toggleChordParentheses(chord, i.second);
}
}

for (EngravingItem* el : selection().elements()) {
cmdAddParentheses(el);
}
Expand All @@ -3408,6 +3428,10 @@ void Score::cmdAddParentheses(EngravingItem* el)
} else if (el->type() == ElementType::TIMESIG) {
TimeSig* ts = toTimeSig(el);
ts->setLargeParentheses(true);
} else if (el->type() == ElementType::NOTE) {
ParenthesesMode p = el->getProperty(Pid::HAS_PARENTHESES).value<ParenthesesMode>()
== ParenthesesMode::BOTH ? ParenthesesMode::NONE : ParenthesesMode::BOTH;
el->undoChangeProperty(Pid::HAS_PARENTHESES, p);
} else {
ParenthesesMode p = el->leftParen() || el->rightParen() ? ParenthesesMode::NONE : ParenthesesMode::BOTH;
el->undoChangeProperty(Pid::HAS_PARENTHESES, p);
Expand Down
Loading
Loading