241 lines
7.7 KiB
C++
241 lines
7.7 KiB
C++
//=============================================================================
|
|
// MuseScore
|
|
// Music Composition & Notation
|
|
//
|
|
// Copyright (C) 2010-2011 Werner Schweer
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License version 2
|
|
// as published by the Free Software Foundation and appearing in
|
|
// the file LICENCE.GPL
|
|
//=============================================================================
|
|
|
|
#ifndef __FRET_H__
|
|
#define __FRET_H__
|
|
|
|
#include "element.h"
|
|
#include "harmony.h"
|
|
|
|
namespace Ms {
|
|
|
|
class StringData;
|
|
class Chord;
|
|
|
|
// Keep this in order - not used directly for comparisons, but the dots will appear in
|
|
// this order in fret multidot mode. See fretproperties.cpp.
|
|
enum class FretDotType : signed char {
|
|
NORMAL = 0,
|
|
CROSS,
|
|
SQUARE,
|
|
TRIANGLE = 3
|
|
};
|
|
|
|
|
|
enum class FretMarkerType : signed char {
|
|
NONE,
|
|
CIRCLE,
|
|
CROSS
|
|
};
|
|
|
|
|
|
class FretItem {
|
|
public:
|
|
struct Barre {
|
|
int startString;
|
|
int endString;
|
|
|
|
Barre() { startString = endString = -1; }
|
|
Barre(int s, int e) : startString(s), endString(e) {}
|
|
bool exists() const { return startString > -1; }
|
|
};
|
|
|
|
struct Dot {
|
|
int fret { 0 };
|
|
FretDotType dtype { FretDotType::NORMAL };
|
|
int fingering; // NOTE:JT - possible future feature?
|
|
|
|
Dot() {}
|
|
Dot(int f, FretDotType t = FretDotType::NORMAL) : fret(f), dtype(t) {}
|
|
bool exists() const { return fret > 0; }
|
|
};
|
|
|
|
struct Marker {
|
|
FretMarkerType mtype;
|
|
|
|
Marker() { mtype = FretMarkerType::NONE; }
|
|
Marker(FretMarkerType t) : mtype(t) {}
|
|
bool exists() const { return mtype != FretMarkerType::NONE; }
|
|
};
|
|
|
|
struct MarkerTypeNameItem {
|
|
FretMarkerType mtype;
|
|
const char* name;
|
|
};
|
|
|
|
struct DotTypeNameItem {
|
|
FretDotType dtype;
|
|
const char* name;
|
|
};
|
|
|
|
static const std::vector<FretItem::MarkerTypeNameItem> markerTypeNameMap;
|
|
static const std::vector<FretItem::DotTypeNameItem> dotTypeNameMap;
|
|
|
|
static QChar markerToChar(FretMarkerType t);
|
|
static QString markerTypeToName(FretMarkerType t);
|
|
static FretMarkerType nameToMarkerType(QString n);
|
|
static QString dotTypeToName(FretDotType t);
|
|
static FretDotType nameToDotType(QString n);
|
|
};
|
|
|
|
|
|
// The three main storage containers used by fret diagrams
|
|
typedef std::map<int, FretItem::Barre> BarreMap;
|
|
typedef std::map<int, FretItem::Marker> MarkerMap;
|
|
typedef std::map<int, std::vector<FretItem::Dot>> DotMap;
|
|
|
|
|
|
class FretUndoData {
|
|
FretDiagram* _diagram { nullptr };
|
|
BarreMap _barres;
|
|
MarkerMap _markers;
|
|
DotMap _dots;
|
|
|
|
public:
|
|
FretUndoData() {}
|
|
FretUndoData(FretDiagram* fd);
|
|
|
|
void updateDiagram();
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// @@ FretDiagram
|
|
/// Fretboard diagram
|
|
//
|
|
// @P userMag qreal
|
|
// @P strings int number of strings
|
|
// @P frets int number of frets
|
|
// @P fretOffset int
|
|
//
|
|
// Note that, while strings are zero-indexed, frets are one-indexed
|
|
//---------------------------------------------------------
|
|
|
|
class FretDiagram final : public Element {
|
|
int _strings { 6 };
|
|
int _frets { 4 };
|
|
int _fretOffset { 0 };
|
|
int _maxFrets { 24 };
|
|
bool _showNut { true };
|
|
|
|
// Barres are stored in the format: K: fret, V: barre struct
|
|
BarreMap _barres;
|
|
|
|
// Dots stored as K: string, V: dot struct
|
|
DotMap _dots;
|
|
|
|
// Markers stored as K: string, V: marker struct
|
|
MarkerMap _markers;
|
|
|
|
Harmony* _harmony { 0 };
|
|
|
|
qreal stringLw;
|
|
qreal nutLw;
|
|
qreal stringDist;
|
|
qreal fretDist;
|
|
QFont font;
|
|
qreal _userMag { 1.0 }; // allowed 0.1 - 10.0
|
|
int _numPos;
|
|
|
|
void removeDot(int s, int f = 0);
|
|
void removeBarre(int f);
|
|
void removeBarres(int string, int fret = 0);
|
|
void removeMarker(int s);
|
|
void removeDotsMarkers(int ss, int es, int fret);
|
|
|
|
public:
|
|
FretDiagram(Score* s);
|
|
FretDiagram(const FretDiagram&);
|
|
~FretDiagram();
|
|
virtual void draw(QPainter*) const override;
|
|
virtual FretDiagram* clone() const override { return new FretDiagram(*this); }
|
|
|
|
Segment* segment() { return toSegment(parent()); }
|
|
|
|
static FretDiagram* fromString(Score* score, const QString &s);
|
|
|
|
virtual ElementType type() const override { return ElementType::FRET_DIAGRAM; }
|
|
virtual void layout() override;
|
|
virtual void write(XmlWriter& xml) const override;
|
|
void writeNew(XmlWriter& xml) const;
|
|
void writeOld(XmlWriter& xml) const;
|
|
virtual void read(XmlReader&) override;
|
|
void readNew(XmlReader&);
|
|
virtual QLineF dragAnchor() const override;
|
|
virtual QPointF pagePos() const override;
|
|
|
|
// read / write MusicXML
|
|
void readMusicXML(XmlReader& de);
|
|
void writeMusicXML(XmlWriter& xml) const;
|
|
|
|
int strings() const { return _strings; }
|
|
int frets() const { return _frets; }
|
|
void setStrings(int n);
|
|
void setFrets(int n) { _frets = n; }
|
|
|
|
void setDot(int string, int fret, bool add = false, FretDotType dtype = FretDotType::NORMAL);
|
|
void setBarre(int startString, int endString, int fret);
|
|
void setBarre(int string, int fret, bool add = false);
|
|
void setMarker(int string, FretMarkerType marker);
|
|
/*void setFingering(int string, int finger);*/
|
|
void clear();
|
|
void undoSetFretDot(int _string, int _fret, bool _add = false, FretDotType _dtype = FretDotType::NORMAL);
|
|
void undoSetFretMarker(int _string, FretMarkerType _mtype);
|
|
void undoSetFretBarre(int _string, int _fret, bool _add = false);
|
|
void undoFretClear();
|
|
int fretOffset() const { return _fretOffset; }
|
|
void setFretOffset(int val) { _fretOffset = val; }
|
|
int maxFrets() const { return _maxFrets; }
|
|
void setMaxFrets(int val) { _maxFrets = val; }
|
|
bool showNut() const { return _showNut; }
|
|
void setShowNut(bool val) { _showNut = val; }
|
|
|
|
QString harmonyText() const { return _harmony ? _harmony->plainText() : QString(); }
|
|
qreal centerX() const;
|
|
void setHarmony(QString harmonyText);
|
|
|
|
std::vector<FretItem::Dot> dot(int s, int f = 0) const;
|
|
FretItem::Marker marker(int s) const;
|
|
FretItem::Barre barre(int fret) const;
|
|
#if 0 // NOTE:JT possible future feature
|
|
int fingering(int s) const { return _fingering ? _fingering[s] : 0; }
|
|
#endif
|
|
|
|
BarreMap barres() const { return _barres; }
|
|
DotMap dots() const { return _dots; }
|
|
MarkerMap markers() const { return _markers; }
|
|
|
|
Harmony* harmony() const { return _harmony; }
|
|
|
|
void init(Ms::StringData *, Chord*);
|
|
|
|
virtual void add(Element*) override;
|
|
virtual void remove(Element*) override;
|
|
|
|
virtual bool acceptDrop(EditData&) const override;
|
|
virtual Element* drop(EditData&) override;
|
|
|
|
void endEditDrag(EditData& editData) override;
|
|
virtual void scanElements(void* data, void (*func)(void*, Element*), bool all=true) override;
|
|
|
|
virtual QVariant getProperty(Pid propertyId) const override;
|
|
virtual bool setProperty(Pid propertyId, const QVariant&) override;
|
|
virtual QVariant propertyDefault(Pid) const override;
|
|
|
|
qreal userMag() const { return _userMag; }
|
|
void setUserMag(qreal m) { _userMag = m; }
|
|
|
|
friend class FretUndoData;
|
|
};
|
|
|
|
|
|
} // namespace Ms
|
|
#endif
|