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 "draw/types/color.h"
26 : #include "spanner.h"
27 :
28 : namespace mu::engraving {
29 : class SLine;
30 : class System;
31 :
32 : //---------------------------------------------------------
33 : // @@ LineSegment
34 : /// Virtual base class for segmented lines segments
35 : /// (OttavaSegment, HairpinSegment, TrillSegment...)
36 : ///
37 : /// This class describes one segment of an segmented
38 : /// line object. Line objects can span multiple staves.
39 : /// For every staff a segment is created.
40 : //---------------------------------------------------------
41 :
42 : class LineSegment : public SpannerSegment
43 : {
44 0 : OBJECT_ALLOCATOR(engraving, LineSegment)
45 : protected:
46 : virtual bool isEditAllowed(EditData&) const override;
47 : virtual bool edit(EditData&) override;
48 : virtual std::vector<LineF> gripAnchorLines(Grip) const override;
49 : virtual void startDragGrip(EditData&) override;
50 : virtual void dragGrip(EditData&) override;
51 : void startDrag(EditData&) override;
52 :
53 : LineSegment(const ElementType& type, SLine* sp, ElementFlags f = ElementFlag::NOTHING);
54 :
55 : public:
56 :
57 : LineSegment(const LineSegment&);
58 5526 : SLine* line() const { return (SLine*)spanner(); }
59 : virtual void spatiumChanged(double, double) override;
60 : virtual void localSpatiumChanged(double, double) override;
61 :
62 : friend class SLine;
63 :
64 : virtual EngravingObject* propertyDelegate(Pid) const override;
65 :
66 0 : bool needStartEditingAfterSelecting() const override { return true; }
67 0 : int gripsCount() const override { return 3; }
68 0 : Grip initialEditModeGrip() const override { return Grip::END; }
69 0 : Grip defaultGrip() const override { return Grip::MIDDLE; }
70 : std::vector<PointF> gripsPositions(const EditData& = EditData()) const override;
71 :
72 : std::vector<LineF> dragAnchorLines() const override;
73 : RectF drag(EditData& ed) override;
74 :
75 : Spatium lineWidth() const;
76 :
77 : double absoluteFromSpatium(const Spatium& sp) const override;
78 :
79 : protected:
80 : virtual void rebaseOffsetsOnAnchorChanged(Grip grip, const PointF& oldPos, System* sys);
81 : virtual void rebaseAnchors(EditData&, Grip);
82 :
83 : private:
84 : void undoMoveStartEndAndSnappedItems(EditData& ed, bool moveStart, bool moveEnd, Segment* s1, Segment* s2);
85 : PointF leftAnchorPosition(const double& systemPositionY) const;
86 : PointF rightAnchorPosition(const double& systemPositionY) const;
87 :
88 : Segment* findSegmentForGrip(Grip grip, PointF pos) const;
89 : static PointF deltaRebaseLeft(const Segment* oldSeg, const Segment* newSeg);
90 : static PointF deltaRebaseRight(const Segment* oldSeg, const Segment* newSeg);
91 : static Fraction lastSegmentEndTick(const Segment* lastSeg, const Spanner* s);
92 : LineSegment* rebaseAnchor(Grip grip, Segment* newSeg);
93 : };
94 :
95 : //---------------------------------------------------------
96 : // @@ SLine
97 : /// virtual base class for Hairpin, Trill and TextLine
98 : //---------------------------------------------------------
99 :
100 : class SLine : public Spanner
101 : {
102 0 : OBJECT_ALLOCATOR(engraving, SLine)
103 :
104 : public:
105 346 : SLine(const ElementType& type, EngravingObject* parent, ElementFlags = ElementFlag::NOTHING);
106 : SLine(const SLine&);
107 :
108 : virtual LineSegment* createLineSegment() = 0;
109 : void setLen(double l);
110 :
111 2674 : bool diagonal() const { return m_diagonal; }
112 258 : void setDiagonal(bool v) { m_diagonal = v; }
113 :
114 3541 : Spatium lineWidth() const { return m_lineWidth; }
115 3357 : Color lineColor() const { return m_lineColor; }
116 2488 : LineType lineStyle() const { return m_lineStyle; }
117 1 : void setLineWidth(const Spatium& v) { m_lineWidth = v; }
118 134 : void setLineColor(const Color& v) { m_lineColor = v; }
119 57 : void setLineStyle(LineType v) { m_lineStyle = v; }
120 :
121 416 : double dashLineLen() const { return m_dashLineLen; }
122 2536 : void setDashLineLen(double val) { m_dashLineLen = val; }
123 416 : double dashGapLen() const { return m_dashGapLen; }
124 2536 : void setDashGapLen(double val) { m_dashGapLen = val; }
125 :
126 3184 : LineSegment* frontSegment() { return toLineSegment(Spanner::frontSegment()); }
127 22 : const LineSegment* frontSegment() const { return toLineSegment(Spanner::frontSegment()); }
128 670 : LineSegment* backSegment() { return toLineSegment(Spanner::backSegment()); }
129 105 : const LineSegment* backSegment() const { return toLineSegment(Spanner::backSegment()); }
130 623 : LineSegment* segmentAt(int n) { return toLineSegment(Spanner::segmentAt(n)); }
131 : const LineSegment* segmentAt(int n) const { return toLineSegment(Spanner::segmentAt(n)); }
132 :
133 : PropertyValue getProperty(Pid id) const override;
134 : bool setProperty(Pid propertyId, const PropertyValue&) override;
135 : PropertyValue propertyDefault(Pid id) const override;
136 :
137 : virtual PointF linePos(Grip grip, System** system) const;
138 0 : virtual bool allowTimeAnchor() const override { return true; }
139 :
140 : void undoMoveStart(Fraction tickDiff);
141 : void undoMoveEnd(Fraction tickDiff);
142 :
143 : static Note* guessFinalNote(Note* startNote);
144 :
145 : private:
146 :
147 : friend class LineSegment;
148 :
149 : Spatium m_lineWidth;
150 : Color m_lineColor;
151 : LineType m_lineStyle = LineType::SOLID;
152 : double m_dashLineLen = 5.0;
153 : double m_dashGapLen = 5.0;
154 : bool m_diagonal = false;
155 : };
156 : }
|