Skip to content

Commit

Permalink
Merge pull request #20139 from miiizen/17625-fb-parts
Browse files Browse the repository at this point in the history
Add figured bass to parts & score
  • Loading branch information
RomanPudashkin committed Nov 24, 2023
2 parents 4958cae + 91947a5 commit 647a6ba
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 19 deletions.
6 changes: 4 additions & 2 deletions src/engraving/dom/edit.cpp
Expand Up @@ -5873,7 +5873,8 @@ void Score::undoAddElement(EngravingItem* element, bool addToLinkedStaves, bool
&& et != ElementType::FRET_DIAGRAM
&& et != ElementType::FERMATA
&& et != ElementType::HARMONY
&& et != ElementType::HARP_DIAGRAM)
&& et != ElementType::HARP_DIAGRAM
&& et != ElementType::FIGURED_BASS)
) {
undo(new AddElement(element));
return;
Expand Down Expand Up @@ -6076,7 +6077,8 @@ void Score::undoAddElement(EngravingItem* element, bool addToLinkedStaves, bool
|| element->isFretDiagram()
|| element->isFermata()
|| element->isHarmony()
|| element->isHarpPedalDiagram()) {
|| element->isHarpPedalDiagram()
|| element->isFiguredBass()) {
Segment* segment
= element->explicitParent()->isFretDiagram() ? toSegment(element->explicitParent()->explicitParent()) : toSegment(
element->explicitParent());
Expand Down
3 changes: 3 additions & 0 deletions src/engraving/dom/engravingobject.h
Expand Up @@ -78,6 +78,7 @@ class FBox;
class FSymbol;
class Fermata;
class FiguredBass;
class FiguredBassItem;
class Fingering;
class FretDiagram;
class Glissando;
Expand Down Expand Up @@ -424,6 +425,7 @@ class EngravingObject
CONVERT(LyricsLine, LYRICSLINE)
CONVERT(LyricsLineSegment, LYRICSLINE_SEGMENT)
CONVERT(FiguredBass, FIGURED_BASS)
CONVERT(FiguredBassItem, FIGURED_BASS_ITEM)
CONVERT(StaffState, STAFF_STATE)
CONVERT(Arpeggio, ARPEGGIO)
CONVERT(Image, IMAGE)
Expand Down Expand Up @@ -799,6 +801,7 @@ CONVERT(NoteHead)
CONVERT(LyricsLine)
CONVERT(LyricsLineSegment)
CONVERT(FiguredBass)
CONVERT(FiguredBassItem)
CONVERT(StaffState)
CONVERT(Arpeggio)
CONVERT(Image)
Expand Down
90 changes: 78 additions & 12 deletions src/engraving/dom/figuredbass.cpp
Expand Up @@ -30,11 +30,13 @@

#include "chord.h"
#include "factory.h"
#include "linkedobjects.h"
#include "measure.h"
#include "note.h"
#include "rest.h"
#include "score.h"
#include "segment.h"
#include "undo.h"

#include "log.h"

Expand Down Expand Up @@ -78,7 +80,7 @@ const Char FiguredBassItem::NORM_PARENTH_TO_CHAR[int(FiguredBassItem::Parenthesi
{ 0, '(', ')', '[', ']' };

FiguredBassItem::FiguredBassItem(FiguredBass* parent, int l)
: EngravingItem(ElementType::INVALID, parent), m_ord(l)
: EngravingItem(ElementType::FIGURED_BASS_ITEM, parent), m_ord(l)
{
m_prefix = m_suffix = Modifier::NONE;
m_digit = FBIDigitNone;
Expand Down Expand Up @@ -706,8 +708,7 @@ Sid FiguredBass::getPropertyStyle(Pid id) const

void FiguredBass::startEdit(EditData& ed)
{
DeleteAll(m_items);
m_items.clear();
clearItems();
renderer()->layoutText1(this); // re-layout without F.B.-specific formatting.
TextBase::startEdit(ed);
}
Expand All @@ -728,6 +729,11 @@ bool FiguredBass::isEditAllowed(EditData& ed) const
void FiguredBass::endEdit(EditData& ed)
{
TextBase::endEdit(ed);
regenerateText();
}

void FiguredBass::regenerateText()
{
// as the standard text editor keeps inserting spurious HTML formatting and styles
// retrieve and work only on the plain text
const String txt = plainText();
Expand All @@ -737,24 +743,20 @@ void FiguredBass::endEdit(EditData& ed)

// split text into lines and create an item for each line
StringList list = txt.split(u'\n', mu::SkipEmptyParts);
DeleteAll(m_items);
m_items.clear();
clearItems();
String normalizedText;
int idx = 0;
for (String str : list) {
FiguredBassItem* pItem = new FiguredBassItem(this, idx++);
if (!pItem->parse(str)) { // if any item fails parsing
DeleteAll(m_items);
m_items.clear(); // clear item list
clearItems();
score()->startCmd();
triggerLayout();
score()->endCmd();
delete pItem;
return;
}
pItem->setTrack(track());
pItem->setParent(this);
m_items.push_back(pItem);
addItemToLinked(pItem);

// add item normalized text
if (!normalizedText.isEmpty()) {
Expand All @@ -764,7 +766,7 @@ void FiguredBass::endEdit(EditData& ed)
}
// if all items parsed and text is styled, replaced entered text with normalized text
if (m_items.size()) {
setXmlText(normalizedText);
undoChangeProperty(Pid::TEXT, normalizedText);
}

score()->startCmd();
Expand Down Expand Up @@ -869,6 +871,13 @@ PropertyValue FiguredBass::getProperty(Pid propertyId) const
bool FiguredBass::setProperty(Pid propertyId, const PropertyValue& v)
{
score()->addRefresh(canvasBoundingRect());
if (propertyId == Pid::TEXT_LINKED_TO_MASTER) {
if (TextBase::setProperty(propertyId, v)) {
regenerateText();
return true;
}
return false;
}
return TextBase::setProperty(propertyId, v);
}

Expand All @@ -877,6 +886,63 @@ PropertyValue FiguredBass::propertyDefault(Pid id) const
return TextBase::propertyDefault(id);
}

void FiguredBass::clearItems()
{
const std::list<EngravingObject*> links = linkList();
for (EngravingObject* linkedObject : links) {
if (!linkedObject || !linkedObject->isFiguredBass()) {
continue;
}
if (linkedObject == this) {
DeleteAll(m_items);
m_items.clear();
} else {
bool isThisTextLinked = getProperty(Pid::TEXT_LINKED_TO_MASTER).toBool();
bool isOtherTextLinked = linkedObject->getProperty(Pid::TEXT_LINKED_TO_MASTER).toBool();
if ((score()->isMaster() && !isOtherTextLinked)
|| (!score()->isMaster() && !isThisTextLinked)) {
continue;
}
FiguredBass* linkedFb = toFiguredBass(linkedObject);
DeleteAll(linkedFb->m_items);
linkedFb->m_items.clear();
}
}
}

void FiguredBass::addItemToLinked(FiguredBassItem* item)
{
const std::list<EngravingObject*> links = linkList();
for (EngravingObject* linkedObject : links) {
if (!linkedObject || !linkedObject->isFiguredBass()) {
continue;
}
Score* linkedScore = linkedObject->score();
if (linkedObject == this) {
item->setTrack(track());
item->setParent(this);
m_items.push_back(item);
score()->undo(new AddElement(item));
} else {
bool isThisTextLinked = getProperty(Pid::TEXT_LINKED_TO_MASTER).toBool();
bool isOtherTextLinked = linkedObject->getProperty(Pid::TEXT_LINKED_TO_MASTER).toBool();
if ((score()->isMaster() && !isOtherTextLinked)
|| (!score()->isMaster() && !isThisTextLinked)) {
continue;
}
FiguredBass* linkedFb = toFiguredBass(linkedObject);
FiguredBassItem* itemClone = item->clone();

itemClone->linkTo(item);
itemClone->setTrack(linkedFb->track());
itemClone->setParent(linkedFb);
itemClone->setScore(linkedFb->score());
linkedFb->appendItem(itemClone);
linkedScore->undo(new AddElement(itemClone));
}
}
}

//---------------------------------------------------------
// STATIC FUNCTION
// adding a new FiguredBass to a Segment;
Expand Down Expand Up @@ -1182,7 +1248,7 @@ FiguredBass* Score::addFiguredBass()
}

FiguredBass* fb;
bool bNew;
bool bNew = true;
if (el->isNote()) {
ChordRest* cr = toNote(el)->chord();
fb = FiguredBass::addFiguredBassToSegment(cr->segment(), cr->staffIdx() * VOICES, Fraction(0, 1), &bNew);
Expand Down
4 changes: 4 additions & 0 deletions src/engraving/dom/figuredbass.h
Expand Up @@ -91,6 +91,7 @@ class FiguredBass;
class FiguredBassItem final : public EngravingItem
{
OBJECT_ALLOCATOR(engraving, FiguredBassItem)
DECLARE_CLASSOF(ElementType::FIGURED_BASS_ITEM)

public:
enum class Modifier : char {
Expand Down Expand Up @@ -275,6 +276,7 @@ class FiguredBass final : public TextBase
void startEdit(EditData&) override;
bool isEditAllowed(EditData&) const override;
void endEdit(EditData&) override;
void regenerateText();

bool onNote() const { return m_onNote; }
void setOnNote(bool val) { m_onNote = val; }
Expand All @@ -292,6 +294,8 @@ class FiguredBass final : public TextBase
size_t itemsCount() const { return m_items.size(); }
void appendItem(FiguredBassItem* item) { m_items.push_back(item); }
const std::vector<FiguredBassItem*>& items() const { return m_items; }
void clearItems();
void addItemToLinked(FiguredBassItem* item);

// the array of configured fonts
static const std::vector<FiguredBassFont>& FBFonts();
Expand Down
4 changes: 2 additions & 2 deletions src/engraving/tests/parts_data/part-image-parts.mscx
Expand Up @@ -126,7 +126,7 @@
<linkedMain/>
<Image>
<Image>
<z>8499</z>
<z>8599</z>
<path>71b2e9f575296b78c22ba721cd71f6e5.png</path>
<linkPath>schnee.png</linkPath>
</Image>
Expand Down Expand Up @@ -848,7 +848,7 @@
</linked>
<Image>
<Image>
<z>8499</z>
<z>8599</z>
<path>71b2e9f575296b78c22ba721cd71f6e5.png</path>
<linkPath>schnee.png</linkPath>
</Image>
Expand Down
4 changes: 2 additions & 2 deletions src/engraving/tests/parts_data/part-image-udel.mscx
Expand Up @@ -126,7 +126,7 @@
<linkedMain/>
<Image>
<Image>
<z>8499</z>
<z>8599</z>
<path>71b2e9f575296b78c22ba721cd71f6e5.png</path>
<linkPath>schnee.png</linkPath>
</Image>
Expand Down Expand Up @@ -849,7 +849,7 @@
</linked>
<Image>
<Image>
<z>8499</z>
<z>8599</z>
<path>71b2e9f575296b78c22ba721cd71f6e5.png</path>
<linkPath>schnee.png</linkPath>
</Image>
Expand Down
2 changes: 1 addition & 1 deletion src/engraving/tests/parts_data/part-image.mscx
Expand Up @@ -122,7 +122,7 @@
<Note>
<Image>
<Image>
<z>8499</z>
<z>8599</z>
<path>71b2e9f575296b78c22ba721cd71f6e5.png</path>
<linkPath>schnee.png</linkPath>
</Image>
Expand Down
1 change: 1 addition & 0 deletions src/engraving/types/types.h
Expand Up @@ -107,6 +107,7 @@ enum class ElementType {
HOOK,
LYRICS,
FIGURED_BASS,
FIGURED_BASS_ITEM,
MARKER,
JUMP,
FINGERING,
Expand Down
1 change: 1 addition & 0 deletions src/engraving/types/typesconv.cpp
Expand Up @@ -202,6 +202,7 @@ static const std::vector<Item<ElementType> > ELEMENT_TYPES = {
{ ElementType::HOOK, "Hook", TranslatableString("engraving", "Flag") }, // internally called "Hook", but "Flag" in SMuFL, so here externally too
{ ElementType::LYRICS, "Lyrics", TranslatableString("engraving", "Lyrics") },
{ ElementType::FIGURED_BASS, "FiguredBass", TranslatableString("engraving", "Figured bass") },
{ ElementType::FIGURED_BASS_ITEM, "FiguredBassItem", TranslatableString("engraving", "Figured bass item") },
{ ElementType::MARKER, "Marker", TranslatableString("engraving", "Marker") },
{ ElementType::JUMP, "Jump", TranslatableString("engraving", "Jump") },
{ ElementType::FINGERING, "Fingering", TranslatableString("engraving", "Fingering") },
Expand Down

0 comments on commit 647a6ba

Please sign in to comment.