diff --git a/src/libs/core/music/ttuneobject.cpp b/src/libs/core/music/ttuneobject.cpp index 5c4cd4934439b5d70cbe60740712e2cf8609b63c..701f70d82f7e7b6133b2f63060cf38da7470bc49 100644 --- a/src/libs/core/music/ttuneobject.cpp +++ b/src/libs/core/music/ttuneobject.cpp @@ -23,7 +23,7 @@ TtuneObject::TtuneObject(QObject* parent) : QObject(parent), - m_tune(nullptr) + m_tuning(nullptr) { } @@ -32,12 +32,42 @@ TtuneObject::~TtuneObject() {} void TtuneObject::setTune(Ttune* t) { - if (t != m_tune) { - m_tune = t; - } + m_tuning = t; + emit scordatureChanged(); } QString TtuneObject::name() const { - return m_tune->name; + return m_tuning->name; +} + + +QString TtuneObject::stringName(int realStrNr) const { + if (realStrNr > 0 && realStrNr <= m_tuning->stringNr()) { + auto strName = m_tuning->str(realStrNr).styledName(false); + return strName.replace(0, 1, strName[0].toUpper()); + } else + return QString(); +} + + +bool TtuneObject::otherThanStd(int realStrNr) const { + return !m_tuning->str(realStrNr).compareNotes(Ttune::stdTune.str(realStrNr)); +} + + +bool TtuneObject::scordature() const { + if (!m_tuning) + return false; + return m_tuning->type() == Ttune::Custom || (m_tuning->type() > Ttune::Standard_EADGBE && m_tuning->type() < Ttune::Bass4_EADG); +} + + +int TtuneObject::changedStrings() const { + int ch = 0; + for (int s = 1; s <= static_cast<int>(m_tuning->stringNr()); ++s) { + if (otherThanStd(s)) + ch++; + } + return ch; } diff --git a/src/libs/core/music/ttuneobject.h b/src/libs/core/music/ttuneobject.h index 7fc919ee801d3aa5cd1008d15484e7d97bd09a02..9aa2d94a79318a6ef9678b2fdefb5b0122449784 100644 --- a/src/libs/core/music/ttuneobject.h +++ b/src/libs/core/music/ttuneobject.h @@ -27,14 +27,17 @@ /** * Wraps @class Ttune with @class QObject + * It is used only by @p Tglobals class. + * It also tracks tuning type for scordature. */ class NOOTKACORE_EXPORT TtuneObject : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name NOTIFY tuningChanged) - Q_PROPERTY(Ttune::Etunings type READ type NOTIFY tuningChanged) + Q_PROPERTY(int type READ typeInt NOTIFY tuningChanged) Q_PROPERTY(int stringNumber READ stringNumber NOTIFY tuningChanged) + Q_PROPERTY(bool scordature READ scordature NOTIFY scordatureChanged) public: @@ -45,17 +48,38 @@ public: QString name() const; - Ttune::Etunings type() const { return m_tune->type(); } + int typeInt() const { return static_cast<int>(m_tuning->type()); } - Q_INVOKABLE Tnote string(int realNr) const { return m_tune->str(realNr); } + Q_INVOKABLE Tnote string(int realStrNr) const { return m_tuning->str(realStrNr); } - int stringNumber() { return static_cast<int>(m_tune->stringNr()); } + /** + * Name of a given string (note name without octave) + */ + Q_INVOKABLE QString stringName(int realStrNr) const; + + /** + * Returns @p TRUE when given string is different than the same string in standard guitar tuning + */ + Q_INVOKABLE bool otherThanStd(int realStrNr) const; + + int stringNumber() { return static_cast<int>(m_tuning->stringNr()); } + + /** + * @p TRUE when tuning is guitar tuning (not bass) and differs from standard EADGBE one + */ + bool scordature() const; + + /** + * Number of strings that were changed (tuned) + */ + Q_INVOKABLE int changedStrings() const; signals: void tuningChanged(); + void scordatureChanged(); private: - Ttune *m_tune; + Ttune *m_tuning; }; diff --git a/src/libs/core/score/tstaffobject.cpp b/src/libs/core/score/tstaffobject.cpp index a150fac7f0bc7246ebef445c911c460fbc9c28f3..8af55332b0c957851cce1358f1b5680f8223a294 100644 --- a/src/libs/core/score/tstaffobject.cpp +++ b/src/libs/core/score/tstaffobject.cpp @@ -46,6 +46,14 @@ TstaffObject::~TstaffObject() { } +void TstaffObject::setScordSpace(int hasScord) { + if (m_scordSpace != hasScord) { + m_scordSpace = hasScord; + checkNotesRange(); + } +} + + void TstaffObject::setScore(TscoreObject* s) { m_score = s; m_score->addStaff(this); @@ -286,11 +294,7 @@ void TstaffObject::findHighestNote() { void TstaffObject::findLowestNote() { -// if (hasScordature()) { TODO -// m_loNotePos = height(); -// return; -// } - m_loNotePos = upperLine() + (m_score->isPianoStaff() ? 24.0 : 14.0); + m_loNotePos = static_cast<qreal>(m_scordSpace) + upperLine() + (m_score->isPianoStaff() ? 24.0 : 14.0); for (int m = m_firstMeasureId; m <= m_lastMeasureId; ++m) { auto measure = m_score->measure(m); for (int n = 0; n < measure->noteCount(); ++n) { diff --git a/src/libs/core/score/tstaffobject.h b/src/libs/core/score/tstaffobject.h index 86bd1c11497b8f47c1a1f412dfbc987f49a9c7be..be44cd6abccfb64ffcffe6f83147571af64441fa 100644 --- a/src/libs/core/score/tstaffobject.h +++ b/src/libs/core/score/tstaffobject.h @@ -47,6 +47,7 @@ class NOOTKACORE_EXPORT TstaffObject : public QObject Q_PROPERTY(qreal notesIndent READ notesIndent WRITE setNotesIndent) Q_PROPERTY(int firstMeasureNr READ firstMeasureNr NOTIFY firstMeasureNrChanged) Q_PROPERTY(int number READ number WRITE setNumber NOTIFY numberChanged) + Q_PROPERTY(int scordSpace READ scordSpace WRITE setScordSpace) friend class TscoreObject; friend class TnotePair; @@ -58,6 +59,13 @@ public: int number() const { return m_number; } void setNumber(int nr) { m_number = nr; emit numberChanged(); } + /** + * @p 0 - means no scordature (standard tuning) + * positive value determines additional space below first staff for scordature marks + */ + int scordSpace() const { return m_scordSpace; } + void setScordSpace(int hasScord); + TscoreObject* score() { return m_score; } void setScore(TscoreObject* s); @@ -183,6 +191,7 @@ private: qreal m_allNotesWidth = 0.0; qreal m_gapsSum = 0.0; QQuickItem *m_extraTie = nullptr; /**< Tie at the staff beginning */ + int m_scordSpace = 0; }; #endif // TSTAFFOBJECT_H diff --git a/src/libs/core/tglobals.cpp b/src/libs/core/tglobals.cpp index eef0e4674805ffc7f9439f19410bea44cca02b76..43e1c64937f3e2905af92904e33d2263de0b5575 100755 --- a/src/libs/core/tglobals.cpp +++ b/src/libs/core/tglobals.cpp @@ -312,7 +312,7 @@ void Tglobals::setGuitarParams(int fretNr, const Ttune& tun) { GfretsNumber = fretNr; doEmit = true; } - if (tun.type() == Ttune::Custom || tun.type() != tuning()->type()) { + if (tun.type() == Ttune::Custom || tun.type() != tuning()->typeInt()) { setTune(tun); doEmit = true; } diff --git a/src/nootka.qrc b/src/nootka.qrc index 5255085a8705e352a779c029ff40e3bc70b8676c..04dffa33565bd4509899bc3db5f602d80a36bfe8 100644 --- a/src/nootka.qrc +++ b/src/nootka.qrc @@ -45,6 +45,7 @@ <file alias="NoteAdd.qml">qml/score/NoteAdd.qml</file> <file alias="DelControl.qml">qml/score/DelControl.qml</file> <file alias="ControlBase.qml">qml/score/ControlBase.qml</file> + <file alias="Scordature.qml">qml/score/Scordature.qml</file> <file alias="Instrument.qml">qml/instruments/Instrument.qml</file> <file alias="instruments/Guitar.qml">qml/instruments/Guitar.qml</file> diff --git a/src/qml/MainScore.qml b/src/qml/MainScore.qml index d06dfdd7a5ceac138ad379f93a4dd291f8ad506e..7643408cb700087178ccc14592705ca102011f11 100644 --- a/src/qml/MainScore.qml +++ b/src/qml/MainScore.qml @@ -73,15 +73,19 @@ Score { x: clef === Tclef.PianoStaffClefs ? 7.5 : 5.5 y: clef === Tclef.PianoStaffClefs ? 3.7 : 6.2 color: activPal.text - font { family: "Sans"; pointSize: 1.3 } + font { family: "Sans"; pixelSize: 2 } text: getKeyNameText() function getKeyNameText() { return enableKeySign && firstStaff.keySignature ? Noo.majAndMinKeyName(firstStaff.keySignature.key) : "" } } + // private + property var scordature: null + Component.onCompleted: { scoreObj.singleNote = GLOB.singleNoteMode + updateScord() } Connections { @@ -96,6 +100,22 @@ Score { } } } + Connections { + target: GLOB.tuning + onScordatureChanged: updateScord() + } + function updateScord() { + if (scordature) { + scordature.destroy() + scordature = null + } + if (GLOB.tuning.scordature && GLOB.instrument.type !== Tinstrument.BassGuitar) { + var c = Qt.createComponent("qrc:/Scordature.qml") + var scordature = c.createObject(firstStaff) + firstStaff.scordSpace = scordature.height + } else + firstStaff.scordSpace = 0 + } Rectangle { // note highlight id: noteHighlight diff --git a/src/qml/score/Scordature.qml b/src/qml/score/Scordature.qml new file mode 100644 index 0000000000000000000000000000000000000000..f700ccf2204c9a34c6ed50e966c1052c4cd3f7da --- /dev/null +++ b/src/qml/score/Scordature.qml @@ -0,0 +1,36 @@ +/** This file is part of Nootka (http://nootka.sf.net) * + * Copyright (C) 2017 by Tomasz Bojczuk (seelook@gmail.com) * + * on the terms of GNU GPLv3 license (http://www.gnu.org/licenses) */ + +import QtQuick 2.9 + +import Nootka 1.0 +import Score 1.0 + + +Grid { + y: upperLine + 14 + (score.clef === Tclef.PianoStaffClefs ? 10 : 0) + x: 0.5 + spacing: 0.5 + scale: columns > 1 ? 0.75 : (score.clef === Tclef.PianoStaffClefs ? 1.4 : 1.2) + transformOrigin: Item.TopLeft + columns: GLOB.tuning.changedStrings() > 3 ? 2 : 1 + visible: score.clef !== Tclef.NoClef + Repeater { + model: 6 + Row { + visible: GLOB.tuning.otherThanStd(index + 1) + height: 2 + Text { + text: (index + 1) + font { pixelSize: 2; family: "Nootka" } + anchors.verticalCenter: parent.verticalCenter + } + Text { + text: "=" + GLOB.tuning.stringName(index + 1) + font { pixelSize: 2; family: "Sans" } + anchors.verticalCenter: parent.verticalCenter + } + } + } +} diff --git a/src/qml/score/Staff.qml b/src/qml/score/Staff.qml index 4c55cc354574a1e4e9b3bbebd0054b914fac9e21..998d2eebb1cd44c948c1ef87a87bfb614057220d 100644 --- a/src/qml/score/Staff.qml +++ b/src/qml/score/Staff.qml @@ -19,6 +19,7 @@ Item { property var keySignature: null property var meter: null property real firstNoteX: (meter ? meter.x + meter.width : (keySignature ? keySignature.x + keySignature.width : 0.5 + clef.width)) + 1.0 + property alias scordSpace: staffObj.scordSpace signal destroing(var nr)