Skip to content

Commit

Permalink
Automatic switching of hairpin type
Browse files Browse the repository at this point in the history
  • Loading branch information
re1san committed Aug 12, 2024
1 parent 8cafdcf commit cf50bc6
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 23 deletions.
49 changes: 33 additions & 16 deletions src/engraving/dom/dynamic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ void Dynamic::editDrag(EditData& ed)
EditTimeTickAnchors::updateAnchors(this, track());

// Right grip (when two grips)
if (int(ed.curGrip) == 1 && !hasLeftHairpin() && !hasRightHairpin()) {
if (int(ed.curGrip) == 1 && hasLeftGrip() && hasRightGrip()) {
m_rightDragOffset += ed.evtDelta.x();
if (rightDragOffset() < 0) {
m_rightDragOffset = 0;
Expand All @@ -740,7 +740,7 @@ void Dynamic::editDrag(EditData& ed)
}

// Right grip (when single grip)
if (int(ed.curGrip) == 0 && hasLeftHairpin() && !hasRightHairpin()) {
if (int(ed.curGrip) == 0 && !hasLeftGrip() && hasRightGrip()) {
m_rightDragOffset += ed.evtDelta.x();
if (rightDragOffset() < 0) {
m_rightDragOffset = 0;
Expand All @@ -749,7 +749,7 @@ void Dynamic::editDrag(EditData& ed)
}

// Left grip (when two grips or single grip)
if (int(ed.curGrip) == 0 && !hasLeftHairpin()) {
if (int(ed.curGrip) == 0 && hasLeftGrip()) {
m_leftDragOffset += ed.evtDelta.x();
if (leftDragOffset() > 0) {
m_leftDragOffset = 0;
Expand Down Expand Up @@ -983,14 +983,35 @@ void Dynamic::drawEditMode(muse::draw::Painter* p, EditData& ed, double currentV
}
}

//---------------------------------------------------------
// hasLeftHairpin
//---------------------------------------------------------

bool Dynamic::hasLeftGrip() const
{
if (segment()->tick().isZero()) {
return false; // Don't show the left grip for the leftmost dynamic with tick zero
}
return m_leftHairpin == nullptr;
}

//---------------------------------------------------------
// hasRightHairpin
//---------------------------------------------------------

bool Dynamic::hasRightGrip() const
{
return m_rightHairpin == nullptr;
}

//---------------------------------------------------------
// findAdjacentHairpins
//---------------------------------------------------------

void Dynamic::findAdjacentHaipins()
void Dynamic::findAdjacentHairpins()
{
m_hasLeftHairpin = false;
m_hasRightHairpin = false;
m_leftHairpin = nullptr;
m_rightHairpin = nullptr;

const Fraction tick = segment()->tick();
const int intTick = tick.ticks();
Expand All @@ -1001,17 +1022,13 @@ void Dynamic::findAdjacentHaipins()
if (sp->track() == track() && sp->isHairpin()) {
Hairpin* hp = toHairpin(sp);
if (hp->tick() == tick) {
m_hasRightHairpin = true;
m_rightHairpin = hp;
} else if (hp->tick2() == tick) {
m_hasLeftHairpin = true;
m_leftHairpin = hp;
}
}
}

if (tick.isZero()) {
m_hasLeftHairpin = true;
}

return;
}

Expand All @@ -1025,9 +1042,9 @@ int Dynamic::gripsCount() const
return 0;
}

if (!hasLeftHairpin() && !hasRightHairpin()) {
if (hasLeftGrip() && hasRightGrip()) {
return 2;
} else if (hasLeftHairpin() ^ hasRightHairpin()) {
} else if (hasLeftGrip() ^ hasRightGrip()) {
return 1;
} else {
return 0;
Expand All @@ -1047,10 +1064,10 @@ std::vector<PointF> Dynamic::gripsPositions(const EditData&) const
PointF leftOffset(-ldata->bbox().width() / 2 - md + m_leftDragOffset, -11.408);
PointF rightOffset(ldata->bbox().width() / 2 + md + m_rightDragOffset, -11.408);

if (!hasLeftHairpin() && hasRightHairpin()) {
if (hasLeftGrip() && !hasRightGrip()) {
return { pp + leftOffset };
}
if (hasLeftHairpin() && !hasRightHairpin()) {
if (!hasLeftGrip() && hasRightGrip()) {
return { pp + rightOffset };
}
return { pp + leftOffset, pp + rightOffset };
Expand Down
13 changes: 8 additions & 5 deletions src/engraving/dom/dynamic.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,19 @@ class Dynamic final : public TextBase
std::vector<PointF> gripsPositions(const EditData& = EditData()) const override;
void drawEditMode(muse::draw::Painter* painter, EditData& editData, double currentViewScaling) override;

bool hasLeftHairpin() const { return m_hasLeftHairpin; }
bool hasRightHairpin() const { return m_hasRightHairpin; }
Hairpin* leftHairpin() const { return m_leftHairpin; }
Hairpin* rightHairpin() const { return m_rightHairpin; }

bool hasLeftGrip() const;
bool hasRightGrip() const;

void resetLeftDragOffset() { m_leftDragOffset = 0.0; }
void resetRightDragOffset() { m_rightDragOffset = 0.0; }

double leftDragOffset() const { return m_leftDragOffset; }
double rightDragOffset() const { return m_rightDragOffset; }

void findAdjacentHaipins();
void findAdjacentHairpins();

RectF adjustedBoundingRect() const;

Expand Down Expand Up @@ -180,8 +183,8 @@ class Dynamic final : public TextBase
double m_leftDragOffset = 0.0;
double m_rightDragOffset = 0.0;

bool m_hasLeftHairpin = false;
bool m_hasRightHairpin = false;
Hairpin* m_leftHairpin = nullptr;
Hairpin* m_rightHairpin = nullptr;
};
} // namespace mu::engraving

Expand Down
2 changes: 1 addition & 1 deletion src/notation/internal/notationinteraction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2601,7 +2601,7 @@ void NotationInteraction::drawGripPoints(muse::draw::Painter* painter)
mu::engraving::EngravingItem* editedElement = m_editData.element;

if (editedElement && editedElement->isDynamic()) {
toDynamic(editedElement)->findAdjacentHaipins();
toDynamic(editedElement)->findAdjacentHairpins();
}

int gripsCount = editedElement ? editedElement->gripsCount() : 0;
Expand Down
52 changes: 51 additions & 1 deletion src/notation/view/internal/dynamicpopupmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,52 @@ static const QList<QList<DynamicPopupModel::PageItem> > DYN_POPUP_PAGES = {
},
};

static bool isValidDynamic(const Dynamic* dyn)
{
if (dyn == nullptr) {
return false;
}
return dyn->dynamicType() >= DynamicType::PPPPPP && dyn->dynamicType() <= DynamicType::FFFFFF;
}

static bool isValidHairpin(Hairpin* pin)
{
return pin->hairpinType() == HairpinType::CRESC_HAIRPIN || pin->hairpinType() == HairpinType::DECRESC_HAIRPIN;
}

static void switchHairpinsType(Dynamic* dyn)
{
if (!isValidDynamic(dyn)) {
return;
}

if (dyn->leftHairpin()) {
Hairpin* leftHairpin = dyn->leftHairpin();
const Dynamic* startDyn = leftHairpin->dynamicSnappedBefore();

if (isValidDynamic(startDyn) && isValidHairpin(leftHairpin)) {
if (int(startDyn->dynamicType()) > int(dyn->dynamicType())) {
leftHairpin->setHairpinType(HairpinType::DECRESC_HAIRPIN);
} else {
leftHairpin->setHairpinType(HairpinType::CRESC_HAIRPIN);
}
}
}

if (dyn->rightHairpin()) {
Hairpin* rightHairpin = dyn->rightHairpin();
const Dynamic* endDyn = rightHairpin->dynamicSnappedAfter();

if (isValidDynamic(endDyn) && isValidHairpin(rightHairpin)) {
if (int(endDyn->dynamicType()) > int(dyn->dynamicType())) {
rightHairpin->setHairpinType(HairpinType::CRESC_HAIRPIN);
} else {
rightHairpin->setHairpinType(HairpinType::DECRESC_HAIRPIN);
}
}
}
}

DynamicPopupModel::DynamicPopupModel(QObject* parent)
: AbstractElementPopupModel(PopupModelType::TYPE_DYNAMIC, parent)
{
Expand Down Expand Up @@ -110,7 +156,11 @@ void DynamicPopupModel::addOrChangeDynamic(int page, int index)
m_item->undoChangeProperty(Pid::DYNAMIC_TYPE, DYN_POPUP_PAGES[page][index].dynType);
endCommand();

m_item->setFlag(ElementFlag::IS_PREVIEW, false);
if (m_item->flag(ElementFlag::IS_PREVIEW)) {
switchHairpinsType(toDynamic(m_item));
m_item->setFlag(ElementFlag::IS_PREVIEW, false);
}

INotationInteractionPtr interaction = currentNotation()->interaction();

// Hide the bounding box which appears when called using Ctrl+D shortcut
Expand Down

0 comments on commit cf50bc6

Please sign in to comment.