Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #pragma once
24 :
25 : #include "slurtie.h"
26 :
27 : namespace mu::engraving {
28 : class TieJumpPointList;
29 : class TieJumpPoint;
30 : //---------------------------------------------------------
31 : // @@ TieSegment
32 : /// a single segment of a tie
33 : //---------------------------------------------------------
34 :
35 : class TieSegment : public SlurTieSegment
36 : {
37 4353 : OBJECT_ALLOCATOR(engraving, TieSegment)
38 : DECLARE_CLASSOF(ElementType::TIE_SEGMENT)
39 :
40 : public:
41 : TieSegment(Tie* sp);
42 : TieSegment(const TieSegment& s);
43 :
44 447 : TieSegment* clone() const override { return new TieSegment(*this); }
45 :
46 24239 : void addAdjustmentOffset(const PointF& offset, Grip grip) { m_adjustmentOffsets[static_cast<size_t>(grip)] += offset; }
47 5351 : void resetAdjustmentOffset() { m_adjustmentOffsets.fill(PointF()); }
48 0 : PointF adjustmentOffset(Grip grip) { return m_adjustmentOffsets[static_cast<size_t>(grip)]; }
49 : void consolidateAdjustmentOffsetIntoUserOffset();
50 :
51 : bool isEdited() const;
52 : RectF drag(EditData&) override;
53 : void dragGrip(EditData&) override;
54 :
55 51880 : Tie* tie() const { return (Tie*)spanner(); }
56 :
57 589 : void setStaffMove(int val) { m_staffMove = val; }
58 25079 : staff_idx_t vStaffIdx() const override { return staffIdx() + m_staffMove; }
59 :
60 : virtual double minShoulderHeight() const;
61 : virtual double maxShoulderHeight() const;
62 : double endWidth() const override;
63 : double midWidth() const override;
64 : double dottedWidth() const override;
65 :
66 : struct LayoutData : public SlurTieSegment::LayoutData {
67 : bool allJumpPointsInactive = false;
68 : };
69 35193 : DECLARE_LAYOUTDATA_METHODS(TieSegment)
70 :
71 : protected:
72 : TieSegment(const ElementType& type, Tie* sp);
73 : void changeAnchor(EditData&, EngravingItem*) override;
74 :
75 : private:
76 : int m_staffMove = 0;
77 : std::array<PointF, static_cast<size_t>(Grip::GRIPS)> m_adjustmentOffsets;
78 : };
79 :
80 : //---------------------------------------------------------
81 : // @@ Tie
82 : //! a Tie has a Note as startElement/endElement
83 : //---------------------------------------------------------
84 :
85 : class Tie : public SlurTie
86 : {
87 4112 : OBJECT_ALLOCATOR(engraving, Tie)
88 1059 : DECLARE_CLASSOF(ElementType::TIE)
89 :
90 : public:
91 : Tie(EngravingObject* parent = 0);
92 : Tie(const Tie& t);
93 :
94 42 : Tie* clone() const override { return new Tie(*this); }
95 :
96 7289 : Anchor anchor() const override { return Anchor::NOTE; }
97 :
98 3855 : virtual ~Tie() {}
99 :
100 : virtual Note* startNote() const;
101 : virtual void setStartNote(Note* note);
102 : virtual Note* endNote() const;
103 1625 : virtual void setEndNote(Note* note) { setEndElement((EngravingItem*)note); }
104 :
105 16278 : bool isInside() const { return m_isInside; }
106 4762 : void setIsInside(bool val) { m_isInside = val; }
107 : virtual bool isOuterTieOfChord(Grip startOrEnd) const;
108 : bool hasTiedSecondInside() const;
109 : bool isCrossStaff() const;
110 :
111 : PropertyValue getProperty(Pid propertyId) const override;
112 : PropertyValue propertyDefault(Pid id) const override;
113 : bool setProperty(Pid propertyId, const PropertyValue& v) override;
114 :
115 101 : TieSegment* frontSegment() { return toTieSegment(Spanner::frontSegment()); }
116 : const TieSegment* frontSegment() const { return toTieSegment(Spanner::frontSegment()); }
117 96 : TieSegment* backSegment() { return toTieSegment(Spanner::backSegment()); }
118 : const TieSegment* backSegment() const { return toTieSegment(Spanner::backSegment()); }
119 5004 : TieSegment* segmentAt(int n) { return toTieSegment(Spanner::segmentAt(n)); }
120 : const TieSegment* segmentAt(int n) const { return toTieSegment(Spanner::segmentAt(n)); }
121 :
122 1907 : SlurTieSegment* newSlurTieSegment() override { return new TieSegment(this); }
123 :
124 : double scalingFactor() const override;
125 :
126 5430 : const TiePlacement& tiePlacement() const { return m_tiePlacement; }
127 5 : void setTiePlacement(const TiePlacement& val) { m_tiePlacement = val; }
128 :
129 : // Outgoing ties before repeats
130 : void updatePossibleJumpPoints();
131 : void addTiesToJumpPoints();
132 : void undoRemoveTiesFromJumpPoints();
133 : virtual bool allJumpPointsInactive() const;
134 : virtual TieJumpPointList* tieJumpPoints();
135 : virtual const TieJumpPointList* tieJumpPoints() const;
136 :
137 : // Incoming ties after repeats
138 1312 : void setJumpPoint(TieJumpPoint* jumpPoint) { m_jumpPoint = jumpPoint; }
139 : void updateStartTieOnRemoval();
140 287 : TieJumpPoint* jumpPoint() const { return m_jumpPoint; }
141 : Tie* startTie() const;
142 :
143 : static void changeTieType(Tie* oldTie, Note* endNote = nullptr);
144 :
145 : protected:
146 : Tie(const ElementType& type, EngravingObject* parent = nullptr);
147 :
148 3075 : bool isInSpannerMap() const override { return false; }
149 :
150 : bool m_isInside = false;
151 : TiePlacement m_tiePlacement = TiePlacement::AUTO;
152 :
153 : // Jump point information for incoming ties after repeats
154 : TieJumpPoint* m_jumpPoint = nullptr;
155 : TieJumpPointList* startTieJumpPoints() const;
156 : };
157 : } // namespace mu::engraving
|