Skip to content
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

BeamBase, Beam and TremoloTwoChord refactor #24820

Merged
merged 7 commits into from
Sep 27, 2024
Merged
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
69 changes: 14 additions & 55 deletions src/engraving/dom/beam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,11 @@
#include "beam.h"

#include <cmath>
#include <set>
#include <algorithm>

#include "containers.h"
#include "realfn.h"

#include "draw/types/brush.h"

#include "actionicon.h"
#include "chord.h"
#include "groups.h"
Expand Down Expand Up @@ -74,13 +71,6 @@ Beam::Beam(const Beam& b)
{
m_elements = b.m_elements;
m_id = b.m_id;
for (const BeamSegment* bs : b.m_beamSegments) {
m_beamSegments.push_back(new BeamSegment(*bs));
}
m_direction = b.m_direction;
m_up = b.m_up;
m_userModified[0] = b.m_userModified[0];
m_userModified[1] = b.m_userModified[1];
m_growLeft = b.m_growLeft;
m_growRight = b.m_growRight;
m_beamDist = b.m_beamDist;
Expand Down Expand Up @@ -222,18 +212,19 @@ const Chord* Beam::findChordWithCustomStemDirection() const

const BeamSegment* Beam::topLevelSegmentForElement(const ChordRest* element) const
{
size_t segmentsSize = m_beamSegments.size();
const std::vector<BeamSegment*>& segments = beamSegments();
size_t segmentsSize = segments.size();

IF_ASSERT_FAILED(segmentsSize > 0) {
return nullptr;
}

const BeamSegment* curSegment = m_beamSegments[0];
const BeamSegment* curSegment = segments[0];
if (segmentsSize == 1) {
return curSegment;
}

for (const BeamSegment* segment : m_beamSegments) {
for (const BeamSegment* segment : segments) {
if (segment->level <= curSegment->level) {
continue;
}
Expand Down Expand Up @@ -322,7 +313,7 @@ void Beam::calcBeamBreaks(const ChordRest* cr, const ChordRest* prevCr, int leve
void Beam::spatiumChanged(double oldValue, double newValue)
{
int idx = directionIdx();
if (m_userModified[idx]) {
if (userModified()) {
double diff = newValue / oldValue;
for (BeamFragment* f : m_fragments) {
f->py1[idx] = f->py1[idx] * diff;
Expand Down Expand Up @@ -429,16 +420,16 @@ std::vector<PointF> Beam::gripsPositions(const EditData& ed) const
// setBeamDirection
//---------------------------------------------------------

void Beam::setBeamDirection(DirectionV d)
void Beam::setDirection(DirectionV d)
{
if (m_direction == d || m_cross) {
if (direction() == d || m_cross) {
return;
}

m_direction = d;
doSetDirection(d);

if (d != DirectionV::AUTO) {
m_up = d == DirectionV::UP;
setUp(d == DirectionV::UP);
}

for (ChordRest* e : elements()) {
Expand Down Expand Up @@ -575,7 +566,7 @@ void Beam::setBeamPos(const PairF& bp)
}
BeamFragment* f = m_fragments.back();
int idx = directionIdx();
m_userModified[idx] = true;
setUserModified(true);
setGenerated(false);

double _spatium = spatium();
Expand All @@ -594,7 +585,7 @@ void Beam::setNoSlope(bool b)
// Make flat if usermodified
if (m_noSlope) {
int idx = directionIdx();
if (m_userModified[idx]) {
if (userModified()) {
BeamFragment* f = m_fragments.back();
f->py1[idx] = f->py2[idx] = (f->py1[idx] + f->py2[idx]) * 0.5;
}
Expand All @@ -603,8 +594,8 @@ void Beam::setNoSlope(bool b)

void Beam::computeAndSetSlope()
{
double xDiff = endAnchor().x() - startAnchor().x();
double yDiff = endAnchor().y() - startAnchor().y();
double xDiff = m_endAnchor.x() - m_startAnchor.x();
double yDiff = m_endAnchor.y() - m_startAnchor.y();
if (std::abs(xDiff) < 0.5 * spatium()) {
// Temporary safeguard: a beam this short is invalid, and exists only as a temporary state,
// so don't try to compute the slope as it will be wrong. Needs a better solution in future.
Expand All @@ -614,37 +605,15 @@ void Beam::computeAndSetSlope()
}
}

//---------------------------------------------------------
// userModified
//---------------------------------------------------------

bool Beam::userModified() const
{
int idx = directionIdx();
return m_userModified[idx];
}

//---------------------------------------------------------
// setUserModified
//---------------------------------------------------------

void Beam::setUserModified(bool val)
{
int idx = directionIdx();
m_userModified[idx] = val;
}

//---------------------------------------------------------
// getProperty
//---------------------------------------------------------

PropertyValue Beam::getProperty(Pid propertyId) const
{
switch (propertyId) {
case Pid::STEM_DIRECTION: return beamDirection();
case Pid::GROW_LEFT: return growLeft();
case Pid::GROW_RIGHT: return growRight();
case Pid::USER_MODIFIED: return userModified();
case Pid::BEAM_POS: return PropertyValue::fromValue(beamPos());
case Pid::BEAM_NO_SLOPE: return noSlope();
case Pid::POSITION_LINKED_TO_MASTER:
Expand All @@ -668,18 +637,12 @@ PropertyValue Beam::getProperty(Pid propertyId) const
bool Beam::setProperty(Pid propertyId, const PropertyValue& v)
{
switch (propertyId) {
case Pid::STEM_DIRECTION:
setBeamDirection(v.value<DirectionV>());
break;
case Pid::GROW_LEFT:
setGrowLeft(v.toDouble());
break;
case Pid::GROW_RIGHT:
setGrowRight(v.toDouble());
break;
case Pid::USER_MODIFIED:
setUserModified(v.toBool());
break;
case Pid::BEAM_POS:
if (userModified()) {
setBeamPos(v.value<PairF>());
Expand Down Expand Up @@ -717,11 +680,8 @@ bool Beam::setProperty(Pid propertyId, const PropertyValue& v)
PropertyValue Beam::propertyDefault(Pid id) const
{
switch (id) {
// case Pid::SUB_STYLE: return int(TextStyleName::BEAM);
case Pid::STEM_DIRECTION: return DirectionV::AUTO;
case Pid::GROW_LEFT: return 1.0;
case Pid::GROW_RIGHT: return 1.0;
case Pid::USER_MODIFIED: return false;
case Pid::BEAM_POS: return PropertyValue::fromValue(beamPos());
default: return BeamBase::propertyDefault(id);
}
Expand Down Expand Up @@ -888,8 +848,7 @@ void Beam::clearBeamSegments()
chordRest->setBeamlet(nullptr);
}

muse::DeleteAll(m_beamSegments);
m_beamSegments.clear();
BeamBase::clearBeamSegments();
}

//-------------------------------------------------------
Expand Down
60 changes: 2 additions & 58 deletions src/engraving/dom/beam.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
#ifndef MU_ENGRAVING_BEAM_H
#define MU_ENGRAVING_BEAM_H

#include <memory>

#include "beambase.h"
#include "engravingitem.h"
#include "property.h"
Expand All @@ -39,46 +37,12 @@ class Beam;
enum class ActionIconType;
enum class SpannerSegmentType;

//---------------------------------------------------------
// BeamFragment
// position of primary beam
// idx 0 - DirectionV::AUTO or DirectionV::DOWN
// 1 - DirectionV::UP
//---------------------------------------------------------

struct BeamFragment {
double py1[2];
double py2[2];
};

class BeamSegment
{
OBJECT_ALLOCATOR(engraving, BeamSegment)
public:
LineF line;
int level = 0;
bool above = false; // above level 0 or below? (meaningless for level 0)
Fraction startTick;
Fraction endTick;
bool isBeamlet = false;
bool isBefore = false;

Shape shape() const;
EngravingItem* parentElement = nullptr;

BeamSegment(EngravingItem* b);
};

struct TremAnchor {
ChordRest* chord1 = nullptr;
double y1 = 0.;
double y2 = 0.;
};

enum class ChordBeamAnchorType {
Start, End, Middle
};

//---------------------------------------------------------
// @@ Beam
//---------------------------------------------------------
Expand Down Expand Up @@ -130,8 +94,7 @@ class Beam final : public BeamBase
void setId(int i) const { m_id = i; }
int id() const { return m_id; }

void setBeamDirection(DirectionV d);
DirectionV beamDirection() const { return m_direction; }
void setDirection(DirectionV d) override;

void calcBeamBreaks(const ChordRest* chord, const ChordRest* prevChord, int level, bool& isBroken32, bool& isBroken64) const;

Expand All @@ -145,9 +108,6 @@ class Beam final : public BeamBase
void setGrowLeft(double val) { m_growLeft = val; }
void setGrowRight(double val) { m_growRight = val; }

bool userModified() const;
void setUserModified(bool val);

PairF beamPos() const;
void setBeamPos(const PairF& bp);
double beamDist() const { return m_beamDist; }
Expand All @@ -164,13 +124,6 @@ class Beam final : public BeamBase
void computeAndSetSlope();
void setSlope(double val) { m_slope = val; }

const PointF& startAnchor() const { return m_startAnchor; }
PointF& startAnchor() { return m_startAnchor; }
void setStartAnchor(const PointF& p) { m_startAnchor = p; }
const PointF& endAnchor() const { return m_endAnchor; }
PointF& endAnchor() { return m_endAnchor; }
void setEndAnchor(const PointF& p) { m_endAnchor = p; }

PropertyValue getProperty(Pid propertyId) const override;
bool setProperty(Pid propertyId, const PropertyValue&) override;
PropertyValue propertyDefault(Pid id) const override;
Expand Down Expand Up @@ -214,9 +167,7 @@ class Beam final : public BeamBase
std::vector<BeamFragment*>& beamFragments() { return m_fragments; }
void addBeamFragment(BeamFragment* f) { m_fragments.push_back(f); }

const std::vector<BeamSegment*>& beamSegments() const { return m_beamSegments; }
std::vector<BeamSegment*>& beamSegments() { return m_beamSegments; }
void clearBeamSegments();
void clearBeamSegments() override;

const StaffType* tab() const { return m_tab; }
void setTab(const StaffType* t) { m_tab = t; }
Expand All @@ -230,8 +181,6 @@ class Beam final : public BeamBase

const BeamSegment* topLevelSegmentForElement(const ChordRest* element) const;

inline int directionIdx() const { return (m_direction == DirectionV::AUTO || m_direction == DirectionV::DOWN) ? 0 : 1; }

private:

friend class Factory;
Expand All @@ -247,10 +196,7 @@ class Beam final : public BeamBase
void removeChordRest(ChordRest* a);

std::vector<ChordRest*> m_elements; // must be sorted by tick
std::vector<BeamSegment*> m_beamSegments;
DirectionV m_direction = DirectionV::AUTO;

bool m_userModified[2]{ false }; // 0: auto/down 1: up
bool m_isGrace = false;
bool m_cross = false;
bool m_fullCross = false;
Expand All @@ -260,8 +206,6 @@ class Beam final : public BeamBase
double m_beamDist = 0.0;
int m_beamSpacing = 3; // how far apart beams are spaced in quarter spaces
double m_beamWidth = 0.0; // how wide each beam is
PointF m_startAnchor;
PointF m_endAnchor;

// for tabs
bool m_isBesideTabStaff = false;
Expand Down
39 changes: 39 additions & 0 deletions src/engraving/dom/beambase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@ BeamBase::BeamBase(const ElementType& type, EngravingItem* parent, ElementFlags
BeamBase::BeamBase(const BeamBase& b)
: EngravingItem(b)
{
for (const BeamSegment* bs : b.m_beamSegments) {
m_beamSegments.push_back(new BeamSegment(*bs));
}
_crossStaffMove = b._crossStaffMove;
m_direction = b.m_direction;
m_up = b.m_up;
m_userModified[0] = b.m_userModified[0];
m_userModified[1] = b.m_userModified[1];
}

void BeamBase::undoChangeProperty(Pid id, const PropertyValue& v, PropertyFlags ps)
Expand All @@ -51,6 +58,10 @@ PropertyValue BeamBase::getProperty(Pid propertyId) const
switch (propertyId) {
case Pid::BEAM_CROSS_STAFF_MOVE:
return crossStaffMove();
case Pid::STEM_DIRECTION:
return direction();
case Pid::USER_MODIFIED:
return userModified();
default:
return EngravingItem::getProperty(propertyId);
}
Expand All @@ -62,6 +73,12 @@ bool BeamBase::setProperty(Pid propertyId, const PropertyValue& v)
case Pid::BEAM_CROSS_STAFF_MOVE:
setCrossStaffMove(v.toInt());
break;
case Pid::STEM_DIRECTION:
setDirection(v.value<DirectionV>());
break;
case Pid::USER_MODIFIED:
setUserModified(v.toBool());
break;
default:
if (!EngravingItem::setProperty(propertyId, v)) {
return false;
Expand All @@ -79,6 +96,10 @@ PropertyValue BeamBase::propertyDefault(Pid propertyId) const
switch (propertyId) {
case Pid::BEAM_CROSS_STAFF_MOVE:
return 0;
case Pid::STEM_DIRECTION:
return DirectionV::AUTO;
case Pid::USER_MODIFIED:
return false;
default:
return EngravingItem::propertyDefault(propertyId);
}
Expand All @@ -100,3 +121,21 @@ bool BeamBase::acceptCrossStaffMove(int move) const
int newCrossStaffIdx = defaultCrossStaffIdx() + move;
return newCrossStaffIdx >= minCRMove() && newCrossStaffIdx <= maxCRMove() + 1;
}

bool BeamBase::userModified() const
{
int idx = directionIdx();
return m_userModified[idx];
}

void BeamBase::setUserModified(bool val)
{
int idx = directionIdx();
m_userModified[idx] = val;
}

void BeamBase::clearBeamSegments()
{
muse::DeleteAll(m_beamSegments);
m_beamSegments.clear();
}
Loading