1 //============================================================================= 2 // MuseScore 3 // Music Composition & Notation 4 // 5 // Copyright (C) 2010-2011 Werner Schweer 6 // 7 // This program is free software; you can redistribute it and/or modify 8 // it under the terms of the GNU General Public License version 2 9 // as published by the Free Software Foundation and appearing in 10 // the file LICENCE.GPL 11 //============================================================================= 12 13 #ifndef __FRET_H__ 14 #define __FRET_H__ 15 16 #include "element.h" 17 #include "harmony.h" 18 19 namespace Ms { 20 21 class StringData; 22 class Chord; 23 24 enum class Orientation : signed char { 25 VERTICAL, 26 HORIZONTAL 27 }; 28 29 // Keep this in order - not used directly for comparisons, but the dots will appear in 30 // this order in fret multidot mode. See fretproperties.cpp. 31 enum class FretDotType : signed char { 32 NORMAL = 0, 33 CROSS, 34 SQUARE, 35 TRIANGLE = 3 36 }; 37 38 39 enum class FretMarkerType : signed char { 40 NONE, 41 CIRCLE, 42 CROSS 43 }; 44 45 46 class FretItem { 47 public: 48 struct Barre { 49 int startString; 50 int endString; 51 BarreBarre52 Barre() { startString = endString = -1; } BarreBarre53 Barre(int s, int e) : startString(s), endString(e) {} existsBarre54 bool exists() const { return startString > -1; } 55 }; 56 57 struct Dot { 58 int fret { 0 }; 59 FretDotType dtype { FretDotType::NORMAL }; 60 int fingering { 0 }; // NOTE:JT - possible future feature? 61 DotDot62 Dot() {} fretDot63 Dot(int f, FretDotType t = FretDotType::NORMAL) : fret(f), dtype(t) {} existsDot64 bool exists() const { return fret > 0; } 65 }; 66 67 struct Marker { 68 FretMarkerType mtype; 69 MarkerMarker70 Marker() { mtype = FretMarkerType::NONE; } MarkerMarker71 Marker(FretMarkerType t) : mtype(t) {} existsMarker72 bool exists() const { return mtype != FretMarkerType::NONE; } 73 }; 74 75 struct MarkerTypeNameItem { 76 FretMarkerType mtype; 77 const char* name; 78 }; 79 80 struct DotTypeNameItem { 81 FretDotType dtype; 82 const char* name; 83 }; 84 85 static const std::vector<FretItem::MarkerTypeNameItem> markerTypeNameMap; 86 static const std::vector<FretItem::DotTypeNameItem> dotTypeNameMap; 87 88 static QChar markerToChar(FretMarkerType t); 89 static QString markerTypeToName(FretMarkerType t); 90 static FretMarkerType nameToMarkerType(QString n); 91 static QString dotTypeToName(FretDotType t); 92 static FretDotType nameToDotType(QString n); 93 }; 94 95 96 // The three main storage containers used by fret diagrams 97 typedef std::map<int, FretItem::Barre> BarreMap; 98 typedef std::map<int, FretItem::Marker> MarkerMap; 99 typedef std::map<int, std::vector<FretItem::Dot>> DotMap; 100 101 102 class FretUndoData { 103 FretDiagram* _diagram { nullptr }; 104 BarreMap _barres; 105 MarkerMap _markers; 106 DotMap _dots; 107 108 public: FretUndoData()109 FretUndoData() {} 110 FretUndoData(FretDiagram* fd); 111 112 void updateDiagram(); 113 }; 114 115 //--------------------------------------------------------- 116 // @@ FretDiagram 117 /// Fretboard diagram 118 // 119 // @P userMag qreal 120 // @P strings int number of strings 121 // @P frets int number of frets 122 // @P fretOffset int 123 // 124 // Note that, while strings are zero-indexed, frets are one-indexed 125 //--------------------------------------------------------- 126 127 class FretDiagram final : public Element { 128 int _strings { 6 }; 129 int _frets { 4 }; 130 int _fretOffset { 0 }; 131 int _maxFrets { 24 }; 132 bool _showNut { true }; 133 Orientation _orientation { Orientation::VERTICAL }; 134 135 // Barres are stored in the format: K: fret, V: barre struct 136 BarreMap _barres; 137 138 // Dots stored as K: string, V: dot struct 139 DotMap _dots; 140 141 // Markers stored as K: string, V: marker struct 142 MarkerMap _markers; 143 144 Harmony* _harmony { nullptr }; 145 146 qreal stringLw; 147 qreal nutLw; 148 qreal stringDist; 149 qreal fretDist; 150 QFont font; 151 qreal _userMag { 1.0 }; // allowed 0.1 - 10.0 152 qreal markerSize; 153 int _numPos; 154 155 void removeDot(int s, int f = 0); 156 void removeBarre(int f); 157 void removeBarres(int string, int fret = 0); 158 void removeMarker(int s); 159 void removeDotsMarkers(int ss, int es, int fret); 160 161 public: 162 FretDiagram(Score* s); 163 FretDiagram(const FretDiagram&); 164 ~FretDiagram(); 165 166 void draw(QPainter*) const override; 167 Element* linkedClone() override; clone()168 FretDiagram* clone() const override { return new FretDiagram(*this); } 169 segment()170 Segment* segment() { return toSegment(parent()); } 171 172 static FretDiagram* fromString(Score* score, const QString &s); 173 type()174 ElementType type() const override { return ElementType::FRET_DIAGRAM; } 175 void layout() override; 176 void write(XmlWriter& xml) const override; 177 void writeNew(XmlWriter& xml) const; 178 void writeOld(XmlWriter& xml) const; 179 void read(XmlReader&) override; 180 void readNew(XmlReader&); 181 QVector<QLineF> dragAnchorLines() const override; 182 QPointF pagePos() const override; 183 184 // read / write MusicXML 185 void readMusicXML(XmlReader& de); 186 void writeMusicXML(XmlWriter& xml) const; 187 strings()188 int strings() const { return _strings; } frets()189 int frets() const { return _frets; } 190 void setStrings(int n); setFrets(int n)191 void setFrets(int n) { _frets = n; } 192 193 void setDot(int string, int fret, bool add = false, FretDotType dtype = FretDotType::NORMAL); 194 void setBarre(int startString, int endString, int fret); 195 void setBarre(int string, int fret, bool add = false); 196 void setMarker(int string, FretMarkerType marker); 197 /*void setFingering(int string, int finger);*/ 198 void clear(); 199 void undoSetFretDot(int _string, int _fret, bool _add = false, FretDotType _dtype = FretDotType::NORMAL); 200 void undoSetFretMarker(int _string, FretMarkerType _mtype); 201 void undoSetFretBarre(int _string, int _fret, bool _add = false); 202 void undoFretClear(); fretOffset()203 int fretOffset() const { return _fretOffset; } setFretOffset(int val)204 void setFretOffset(int val) { _fretOffset = val; } maxFrets()205 int maxFrets() const { return _maxFrets; } setMaxFrets(int val)206 void setMaxFrets(int val) { _maxFrets = val; } showNut()207 bool showNut() const { return _showNut; } setShowNut(bool val)208 void setShowNut(bool val) { _showNut = val; } 209 harmonyText()210 QString harmonyText() const { return _harmony ? _harmony->plainText() : QString(); } 211 qreal centerX() const; 212 void setHarmony(QString harmonyText); 213 214 std::vector<FretItem::Dot> dot(int s, int f = 0) const; 215 FretItem::Marker marker(int s) const; 216 FretItem::Barre barre(int fret) const; 217 #if 0 // NOTE:JT possible future feature 218 int fingering(int s) const { return _fingering ? _fingering[s] : 0; } 219 #endif 220 barres()221 BarreMap barres() const { return _barres; } dots()222 DotMap dots() const { return _dots; } markers()223 MarkerMap markers() const { return _markers; } 224 harmony()225 Harmony* harmony() const { return _harmony; } 226 227 void init(Ms::StringData*, Chord*); 228 229 void add(Element*) override; 230 void remove(Element*) override; 231 232 bool acceptDrop(EditData&) const override; 233 Element* drop(EditData&) override; 234 235 void endEditDrag(EditData& editData) override; 236 void scanElements(void* data, void (*func)(void*, Element*), bool all=true) override; 237 238 QVariant getProperty(Pid propertyId) const override; 239 bool setProperty(Pid propertyId, const QVariant&) override; propertyDefault(Pid)240 QVariant propertyDefault(Pid) const override; 241 242 qreal userMag() const { return _userMag; } setUserMag(qreal m)243 void setUserMag(qreal m) { _userMag = m; } 244 245 virtual QString accessibleInfo() const override; 246 virtual QString screenReaderInfo() const override; 247 248 friend class FretUndoData; 249 }; 250 251 252 } // namespace Ms 253 #endif 254