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 <array>
26 :
27 : #include "engravingitem.h"
28 : #include "draw/types/painterpath.h"
29 :
30 : #include "../types/types.h"
31 :
32 : namespace mu::engraving {
33 : class Factory;
34 :
35 : class Chord;
36 : class Note;
37 :
38 : //---------------------------------------------------------
39 : // @@ ChordLine
40 : /// bezier line attached to top note of a chord
41 : /// implements fall, doit, plop, bend
42 : //---------------------------------------------------------
43 :
44 : class ChordLine final : public EngravingItem
45 : {
46 284 : OBJECT_ALLOCATOR(engraving, ChordLine)
47 1866 : DECLARE_CLASSOF(ElementType::CHORDLINE)
48 :
49 : public:
50 :
51 4 : ChordLine* clone() const override { return new ChordLine(*this); }
52 :
53 672 : Chord* chord() const { return (Chord*)(ownershipParent()); }
54 :
55 : void setChordLineType(ChordLineType);
56 195 : ChordLineType chordLineType() const { return m_chordLineType; }
57 179 : bool isStraight() const { return m_straight; }
58 99 : void setStraight(bool straight) { m_straight = straight; }
59 526 : bool isWavy() const { return m_wavy; }
60 9 : void setWavy(bool wavy) { m_wavy = wavy; }
61 :
62 : // The shape is described by up to four points: the default points, in spatium units, plus the user's
63 : // offsets of these points, in absolute units. Both are at the chord's normal size: layout scales the
64 : // whole shape by the chord's intrinsic mag.
65 : enum class Point : unsigned char {
66 : START,
67 : BEZIER1,
68 : BEZIER2,
69 : END,
70 : POINTS_COUNT
71 : };
72 : using Points = std::array<PointF, static_cast<size_t>(Point::POINTS_COUNT)>;
73 :
74 : Points defaultPoints() const;
75 174 : const Points& bezierOffsets() const { return m_bezierOffsets; }
76 418 : const PointF& bezierOffset(Point point) const { return m_bezierOffsets[size_t(point)]; }
77 27 : void setBezierOffset(Point point, const PointF& offset) { m_bezierOffsets[size_t(point)] = offset; }
78 : static Pid bezierOffsetPid(Point point);
79 :
80 : double chordMag() const;
81 :
82 : const TranslatableString& chordLineTypeName() const;
83 :
84 : void startDragGrip(EditData&) override;
85 : void dragGrip(EditData&) override;
86 :
87 : String accessibleInfo() const override;
88 :
89 : int subtype() const override;
90 : TranslatableString subtypeUserName() const override;
91 :
92 : PropertyValue getProperty(Pid propertyId) const override;
93 : bool setProperty(Pid propertyId, const PropertyValue&) override;
94 : PropertyValue propertyDefault(Pid) const override;
95 : void reset() override;
96 :
97 : void spatiumChanged(double oldValue, double newValue) override;
98 : void localSpatiumChanged(double oldValue, double newValue) override;
99 :
100 0 : bool needStartEditingAfterSelecting() const override { return true; }
101 : int gripsCount() const override;
102 0 : Grip initialEditModeGrip() const override { return Grip(gripsCount() - 1); }
103 0 : Grip defaultGrip() const override { return initialEditModeGrip(); }
104 : std::vector<PointF> gripsPositions(const EditData&) const override;
105 :
106 866 : bool isToTheLeft() const { return m_chordLineType == ChordLineType::PLOP || m_chordLineType == ChordLineType::SCOOP; }
107 352 : bool isBelow() const { return m_chordLineType == ChordLineType::SCOOP || m_chordLineType == ChordLineType::FALL; }
108 :
109 5 : bool playChordLine() const { return m_playChordLine; }
110 1 : void setPlayChordLine(bool val) { m_playChordLine = val; }
111 :
112 : void setNote(Note* note);
113 578 : Note* note() const { return m_note; }
114 :
115 : SymId waveSym() const;
116 :
117 : struct LayoutData : public EngravingItem::LayoutData {
118 : muse::draw::PainterPath path;
119 : };
120 160 : DECLARE_LAYOUTDATA_METHODS(ChordLine)
121 :
122 : private:
123 :
124 : friend class Factory;
125 :
126 : ChordLine(DummyParentOr<Chord> parent);
127 : ChordLine(const ChordLine&);
128 :
129 : Point gripPoint(Grip grip) const;
130 :
131 : bool m_straight = false;
132 : bool m_wavy = false;
133 :
134 : ChordLineType m_chordLineType = ChordLineType::NOTYPE;
135 : Points m_bezierOffsets;
136 : bool m_playChordLine = true;
137 : Note* m_note = nullptr;
138 : };
139 : }
|