From 3abf6774039af45e9ab911592a3696a7c4d5ade2 Mon Sep 17 00:00:00 2001 From: SeeLook <945374+SeeLook@users.noreply.github.com> Date: Tue, 31 Jan 2017 23:26:37 +0100 Subject: [PATCH] Implemented note segment pure in c++, by creating QML items from TnoteObject class. Staff and Score have corresponding c++ objects to manage score with c++ --- src/libs/core/CMakeLists.txt | 20 +-- src/libs/core/score/tnoteobject.cpp | 197 +++++++++++++++++++++++++++ src/libs/core/score/tnoteobject.h | 84 ++++++++++++ src/libs/core/score/tscoreobject.cpp | 64 +++++++++ src/libs/core/score/tscoreobject.h | 83 +++++++++++ src/libs/core/score/tstaffobject.cpp | 66 +++++++++ src/libs/core/score/tstaffobject.h | 73 ++++++++++ src/libs/core/tnootkaqml.cpp | 13 +- src/libs/core/tnootkaqml.h | 2 + src/nootka.qrc | 1 - src/qml/MainWindow.qml | 5 + src/qml/score/NoteSegment.qml | 70 +++++++--- src/qml/score/Score.qml | 5 + src/qml/score/Staff.qml | 21 +-- 14 files changed, 668 insertions(+), 36 deletions(-) create mode 100644 src/libs/core/score/tnoteobject.cpp create mode 100644 src/libs/core/score/tnoteobject.h create mode 100644 src/libs/core/score/tscoreobject.cpp create mode 100644 src/libs/core/score/tscoreobject.h create mode 100644 src/libs/core/score/tstaffobject.cpp create mode 100644 src/libs/core/score/tstaffobject.h diff --git a/src/libs/core/CMakeLists.txt b/src/libs/core/CMakeLists.txt index e1159f7d2..52335caf8 100644 --- a/src/libs/core/CMakeLists.txt +++ b/src/libs/core/CMakeLists.txt @@ -31,14 +31,18 @@ set(LIB_NOOTKACORE_SRC music/tmelody.cpp music/tmeter.cpp - exam/tqatype.cpp - exam/tqaunit.cpp - exam/tqagroup.cpp - exam/tattempt.cpp - exam/tlevel.cpp - exam/texam.cpp - exam/textrans.h - exam/tresulttext.cpp + score/tscoreobject.cpp + score/tstaffobject.cpp + score/tnoteobject.cpp + +# exam/tqatype.cpp +# exam/tqaunit.cpp +# exam/tqagroup.cpp +# exam/tattempt.cpp +# exam/tlevel.cpp +# exam/texam.cpp +# exam/textrans.h +# exam/tresulttext.cpp touch/ttouchproxy.cpp diff --git a/src/libs/core/score/tnoteobject.cpp b/src/libs/core/score/tnoteobject.cpp new file mode 100644 index 000000000..7b10dbfcd --- /dev/null +++ b/src/libs/core/score/tnoteobject.cpp @@ -0,0 +1,197 @@ +/*************************************************************************** + * Copyright (C) 2017 by Tomasz Bojczuk * + * seelook@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#include "tnoteobject.h" +#include "tstaffobject.h" +#include "tscoreobject.h" +#include "music/tnote.h" +#include <QtQml/qqmlengine.h> +#include <QtGui/qguiapplication.h> +#include <QtGui/qpalette.h> + +#include <QtCore/qdebug.h> + + +/** Unicode numbers of accidentals in Scorek font. */ +static const QString accCharTable[6] = { + QStringLiteral("\ue264"), // [0] = bb - double flat + QStringLiteral("\ue260"), // [1] = b - flat + QString(), // [2] = none + QStringLiteral("\ue262"), // [3] = # - sharp + QStringLiteral("\ue263"), // [4] = x - double sharp + QStringLiteral("\ue261") // [5] = neutral +}; + +/** + * Width of every accidental for Scorek font size set to 7.0 + * It was measured by QML and corresponds to QFont size @p QFont::setPointSizeF(5.5) (except of neutral) + */ +static const qreal accWidthTable[6] = { 2.78125, 1.671875, 0.0, 1.765625, 2.03125, 2.34375 }; + + +TnoteObject::TnoteObject(TstaffObject* staffObj, QQuickItem* parent) : + QQuickItem(parent), + m_staff(staffObj), + m_index(-1), + m_stemHeight(6.0) +{ + m_note = new Tnote(); + QQmlEngine engine; + QQmlComponent comp(&engine, this); + + comp.setData("import QtQuick 2.7; Rectangle {}", QUrl()); + m_stem = qobject_cast<QQuickItem*>(comp.create()); + m_stem->setParentItem(this); + m_stem->setWidth(0.3); + m_stem->setHeight(m_stemHeight); + m_stem->setVisible(false); + + for (int i = 0; i < 7; ++i) { + m_upperLines << createAddLine(comp); + m_upperLines.last()->setY(2 * (i + 1) - 0.1); + m_lowerLines << createAddLine(comp); + m_lowerLines.last()->setY(staff()->upperLine() + 10.0 + 2 * i - 0.1); + } + + comp.setData("import QtQuick 2.7; Text { font { family: \"Scorek\"; pixelSize: 7 }}", QUrl()); + m_head = qobject_cast<QQuickItem*>(comp.create()); + m_head->setParentItem(this); + + m_alter = qobject_cast<QQuickItem*>(comp.create()); + m_alter->setParentItem(m_head); + + m_flag = qobject_cast<QQuickItem*>(comp.create()); + m_flag->setParentItem(m_stem); + m_flag->setX(0.1); + + + setColor(qApp->palette().text().color()); +} + + +TnoteObject::~TnoteObject() { + delete m_note; +} + + +void TnoteObject::setColor(const QColor& c) { + m_head->setProperty("color", c); + m_alter->setProperty("color", c); + m_flag->setProperty("color", c); + m_stem->setProperty("color", c); +} + + +void TnoteObject::setNote(const Tnote& n) { + *m_note = n; + + m_note->rtm.setRhythm(static_cast<Trhythm::Erhythm>(4 + m_index % 2)); // TODO fake + + m_head->setProperty("text", getHeadText()); + setNotePosY(staff()->score()->clefOffset().total() + staff()->upperLine() - (n.octave * 7 + (n.note - 1))); + if (m_notePosY < 1.0 || m_notePosY > 38.0) + m_notePosY = 0.0; + if (static_cast<int>(m_notePosY) != static_cast<int>(m_head->y())) { + if (m_notePosY) { + m_head->setVisible(true); + m_head->setY(m_notePosY - 15.0); + for (int i = 0; i < 7; ++i) { + m_upperLines[i]->setVisible(m_notePosY > 0.0 && i >= qFloor((m_notePosY - 1.0) / 2.0)); + m_lowerLines[i]->setVisible(staff()->upperLine() + 10.0 + i * 2 <= m_notePosY); + } + } else { + m_head->setVisible(false); + } + } + + if (m_notePosY && !m_note->isRest() && m_note->rhythm() > Trhythm::e_whole ) { + if (m_note->rtm.beam() == Trhythm::e_noBeam) { + m_note->rtm.setStemDown(m_notePosY < staff()->upperLine() + 4.0); + m_stem->setHeight(qMax(6.0, qAbs(m_notePosY - (staff()->upperLine() + 4.0)))); + } + m_stem->setX(m_head->x() + (m_note->rtm.stemDown() ? 0.0 : 2.0)); + m_stem->setY(m_notePosY + (m_note->rtm.stemDown() ? 0.0 : - m_stem->height())); + m_stem->setVisible(true); + } else + m_stem->setVisible(false); + + m_alter->setProperty("text", getAccidText()); + if (m_note->alter) + m_alter->setX(-m_alter->width() - 0.1); + + if (m_stem->isVisible()) { + QString flag = getFlagText(); + m_flag->setProperty("text", flag); + if (!flag.isEmpty()) { + m_flag->setY((m_note->rtm.stemDown() ? m_stem->height() : 0.0) - 15.0); + } + } + + qDebug() << "[TnoteObject] set note" << m_note->toText() << m_note->rtm.string(); +} + + +/** Overrides standard @p setX() method to shift note segment about accidental symbol width (if it is set) */ +void TnoteObject::setX(qreal xx) { + QQuickItem::setX(xx + (m_note->alter ? m_alter->width() : 0.0)); +} + + +//################################################################################################# +//################### PROTECTED ############################################ +//################################################################################################# + +QString TnoteObject::getAccidText() { + return accCharTable[m_note->alter + 2]; +} + + +/** Used glyphs are note heads: @p 0xf4be @p 0xf4bd (half and black over-sized) and @p 0xf486 (whole smaller) */ +QString TnoteObject::getHeadText() { + if (m_note->rhythm() == Trhythm::e_none) + return QStringLiteral("\uf4be"); // just black note-head + if (m_note->isRest()) { + + } else { + if (m_note->rhythm() == Trhythm::e_whole) + return QStringLiteral("\uf468"); + else if (m_note->rhythm() == Trhythm::e_half) + return QStringLiteral("\uf4bd"); + else + return QStringLiteral("\uf4be"); // black note head + } +} + + +QString TnoteObject::getFlagText() { + if (m_note->rhythm() < Trhythm::e_eighth || m_note->isRest() || m_note->rtm.beam() != Trhythm::e_noBeam) + return QString(); + return QString(QChar(0xe240 + (static_cast<int>(m_note->rhythm()) - 4) * 2 + (m_note->rtm.stemDown() ? 1 : 0))); +} + + +QQuickItem* TnoteObject::createAddLine(QQmlComponent& comp) { + auto line = qobject_cast<QQuickItem*>(comp.create()); + line->setParentItem(this); + line->setWidth(3.5); + line->setHeight(0.2); + line->setX(-0.5); + line->setVisible(false); + line->setProperty("color", qApp->palette().text().color()); + return line; +} diff --git a/src/libs/core/score/tnoteobject.h b/src/libs/core/score/tnoteobject.h new file mode 100644 index 000000000..48e096714 --- /dev/null +++ b/src/libs/core/score/tnoteobject.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2017 by Tomasz Bojczuk * + * seelook@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef TNOTEOBJECT_H +#define TNOTEOBJECT_H + + +#include "nootkacoreglobal.h" +#include <QtQuick/qquickitem.h> + + +class TstaffObject; +class Tnote; + + +class NOOTKACORE_EXPORT TnoteObject : public QQuickItem +{ + + Q_OBJECT + + Q_PROPERTY(qreal notePosY READ notePosY WRITE setNotePosY NOTIFY notePosYchanged) + +public: + explicit TnoteObject(TstaffObject* staffObj = nullptr, QQuickItem* parent = nullptr); + ~TnoteObject(); + + TstaffObject* staff() const { return m_staff; } + + Tnote* note() { return m_note; } + void setNote(const Tnote& n); + + qreal notePosY() const { return m_notePosY; } + qreal setNotePosY(qreal y) { m_notePosY = y; emit notePosYchanged(); } + + int index() const { return m_index; } + void setIndex(int id) { m_index = id; } + + qreal stemHeight() const { return m_stemHeight; } + void setStemHEight(qreal sh); + + QColor color() { return m_head->property("color").value<QColor>(); } + void setColor(const QColor& c); + + void setX(qreal xx); + +signals: + void notePosYchanged(); + +protected: + QString getAccidText(); + QString getHeadText(); + QString getFlagText(); + +private: + + TstaffObject *m_staff; + Tnote *m_note; + int m_index; + qreal m_notePosY; + qreal m_x; + QQuickItem *m_head, *m_alter, *m_stem, *m_flag; + QList<QQuickItem*> m_upperLines, m_lowerLines; + qreal m_stemHeight; + +private: + QQuickItem* createAddLine(QQmlComponent& comp); +}; + +#endif // TNOTEOBJECT_H diff --git a/src/libs/core/score/tscoreobject.cpp b/src/libs/core/score/tscoreobject.cpp new file mode 100644 index 000000000..1b6f6ff0a --- /dev/null +++ b/src/libs/core/score/tscoreobject.cpp @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2017 by Tomasz Bojczuk * + * seelook@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#include "tscoreobject.h" +#include "tstaffobject.h" +#include "music/tmeter.h" +#include "music/tnote.h" +#include <QtCore/qdebug.h> + + + +TscoreObject::TscoreObject(QObject* parent) : + QObject(parent), + m_keySignEnabled(false), + m_clefOffset(TclefOffset(3, 1)) +{ + m_meter = new Tmeter(Tmeter::Meter_4_4); +} + + +TscoreObject::~TscoreObject() +{ + delete m_meter; + qDebug() << "[TscoreObject] deleted"; +} + + +void TscoreObject::setParent(QObject* p) { + QObject::setParent(p); + qDebug() << "[TscoreObject] parent changed to" << p; +} + + +void TscoreObject::addNote(const Tnote& n) { + m_staves.last()->addNote(n); +} + + +void TscoreObject::setKeySignatureEnabled(bool enKey) { + m_keySignEnabled = enKey; +} + + +//################################################################################################# +//################### PROTECTED ############################################ +//################################################################################################# +void TscoreObject::addStaff(TstaffObject* st) { + m_staves.append(st); +} diff --git a/src/libs/core/score/tscoreobject.h b/src/libs/core/score/tscoreobject.h new file mode 100644 index 000000000..103d4662e --- /dev/null +++ b/src/libs/core/score/tscoreobject.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (C) 2017 by Tomasz Bojczuk * + * seelook@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef TSCOREOBJECT_H +#define TSCOREOBJECT_H + + +#include "nootkacoreglobal.h" +#include <QtCore/qobject.h> + + +/** + * Describes offset of a note. + */ +class TclefOffset +{ +public: + TclefOffset(qint8 noteOff = 0, qint8 octaveOff = 0) : note(noteOff), octave(octaveOff) {} + + qint8 note; + qint8 octave; + int total() { return octave * 7 + note; } +}; + + + +class Tnote; +class TstaffObject; +class TnoteObject; +class Tmeter; + + + +class NOOTKACORE_EXPORT TscoreObject : public QObject +{ + + Q_OBJECT + + Q_PROPERTY(QObject* parent READ parent WRITE setParent) + + friend class TstaffObject; + friend class TnoteObject; + +public: + explicit TscoreObject(QObject* parent = nullptr); + ~TscoreObject(); + + void setParent(QObject* p); + + Q_INVOKABLE void addNote(const Tnote& n); + + bool keySignatureEnabled() const { return m_keySignEnabled; } + void setKeySignatureEnabled(bool enKey); + +protected: + void addStaff(TstaffObject* st); + + TclefOffset clefOffset() const { return m_clefOffset; } + +private: + Tmeter *m_meter; + bool m_keySignEnabled; + TclefOffset m_clefOffset; + QList<TstaffObject*> m_staves; + +}; + +#endif // TSCOREOBJECT_H diff --git a/src/libs/core/score/tstaffobject.cpp b/src/libs/core/score/tstaffobject.cpp new file mode 100644 index 000000000..97b145e9e --- /dev/null +++ b/src/libs/core/score/tstaffobject.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2017 by Tomasz Bojczuk * + * seelook@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#include "tstaffobject.h" +#include <QtCore/qdebug.h> +#include "tscoreobject.h" +#include "tnoteobject.h" +#include "music/tnote.h" + + +TstaffObject::TstaffObject(QObject* parent) : + QObject(parent), + m_score(nullptr), + m_upperLine(16.0), + m_staffItem(nullptr) +{ +} + + +TstaffObject::~TstaffObject() { qDebug() << "[TstaffObject] is going delete"; } + + +void TstaffObject::setScore(TscoreObject* s) { + m_score = s; + setParent(s); + qDebug() << "TstaffObject got a score parent" << s; + m_score->addStaff(this); +} + + +void TstaffObject::addNote(const Tnote& n) { + auto noteObj = new TnoteObject(this, m_staffItem); + noteObj->setIndex(m_notes.count()); + noteObj->setNote(n); + noteObj->setX(notesIndent() + noteObj->index() * 7.0); + m_notes.append(noteObj); + emit noteAdded(noteObj); +} + + +void TstaffObject::setUpperLine(qreal upLine) { + m_upperLine = upLine; + emit upperLineChanged(); +} + + +void TstaffObject::setStaffItem(QQuickItem* si) { + m_staffItem = si; +} + + diff --git a/src/libs/core/score/tstaffobject.h b/src/libs/core/score/tstaffobject.h new file mode 100644 index 000000000..707fdf25f --- /dev/null +++ b/src/libs/core/score/tstaffobject.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2017 by Tomasz Bojczuk * + * seelook@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef TSTAFFOBJECT_H +#define TSTAFFOBJECT_H + + +#include "nootkacoreglobal.h" +#include <QtCore/qobject.h> + + +class QQuickItem; +class TscoreObject; +class TnoteObject; +class Tnote; + + +class NOOTKACORE_EXPORT TstaffObject : public QObject +{ + + Q_OBJECT + + Q_PROPERTY(TscoreObject* score READ score WRITE setScore) + Q_PROPERTY(qreal upperLine READ upperLine WRITE setUpperLine NOTIFY upperLineChanged) + Q_PROPERTY(QQuickItem* staffItem READ staffItem WRITE setStaffItem) + Q_PROPERTY(qreal notesIndent READ notesIndent WRITE setNotesIndent) + +public: + explicit TstaffObject(QObject* parent = nullptr); + ~TstaffObject(); + + TscoreObject* score() { return m_score; } + void setScore(TscoreObject* s); + + void addNote(const Tnote& n); + + qreal upperLine() { return m_upperLine; } + void setUpperLine(qreal upLine); + + QQuickItem* staffItem() { return m_staffItem; } + void setStaffItem(QQuickItem* si); + + qreal notesIndent() { return m_notesIndent; } + void setNotesIndent(qreal ni) { m_notesIndent = ni; } + +signals: + void noteAdded(TnoteObject* note); + void upperLineChanged(); + +private: + TscoreObject *m_score; + qreal m_upperLine; + QList<TnoteObject*> m_notes; + QQuickItem *m_staffItem; + qreal m_notesIndent; +}; + +#endif // TSTAFFOBJECT_H diff --git a/src/libs/core/tnootkaqml.cpp b/src/libs/core/tnootkaqml.cpp index 75d112ac8..9e1838f31 100644 --- a/src/libs/core/tnootkaqml.cpp +++ b/src/libs/core/tnootkaqml.cpp @@ -19,10 +19,12 @@ #include "tnootkaqml.h" #include "ttickcolors.h" #include "nootkaconfig.h" -#include "music/tmeter.h" #include "tpath.h" +#include "music/tmeter.h" #include "music/tclef.h" #include "music/tkeysignature.h" +#include "score/tscoreobject.h" +#include "score/tstaffobject.h" #include <QtQml/qqmlengine.h> #include <QtCore/qfile.h> #include <QtCore/qdir.h> @@ -45,6 +47,10 @@ TnootkaQML::TnootkaQML(QObject* parent) : qmlRegisterUncreatableType<Tclef>("Score", 1, 0, "Tclef", "You cannot create an instance of the Tclef."); qRegisterMetaType<Tmeter>(); qmlRegisterUncreatableType<Tmeter>("Score", 1, 0, "Tmeter", "You cannot create an instance of the Tmeter."); + + qmlRegisterType<TscoreObject>("Score", 1, 0, "TscoreObject"); + qmlRegisterType<TstaffObject>("Score", 1, 0, "TstaffObject"); + qmlRegisterType<TtickColors>("TtickColors", 1, 0, "TtickColors"); } @@ -71,6 +77,11 @@ Tmeter TnootkaQML::meter(int m) { } +Tnote TnootkaQML::note(int pitch, int octave, int alter) { + return Tnote(static_cast<char>(pitch), static_cast<char>(octave), static_cast<char>(alter), Trhythm(Trhythm::e_quarter)); +} + + QString TnootkaQML::majorKeyName(int key) { return TkeySignature(static_cast<char>(key)).getMajorName(); } diff --git a/src/libs/core/tnootkaqml.h b/src/libs/core/tnootkaqml.h index 075d7cb0d..f34db4d9d 100644 --- a/src/libs/core/tnootkaqml.h +++ b/src/libs/core/tnootkaqml.h @@ -26,6 +26,7 @@ class Tclef; class Tmeter; +class Tnote; /** @@ -45,6 +46,7 @@ public: Q_INVOKABLE QString version(); Q_INVOKABLE Tclef clef(int type); Q_INVOKABLE Tmeter meter(int m); + Q_INVOKABLE Tnote note(int pitch, int octave, int alter); Q_INVOKABLE QString majorKeyName(int key); Q_INVOKABLE QString minorKeyName(int key); Q_INVOKABLE QString getLicense(); diff --git a/src/nootka.qrc b/src/nootka.qrc index afc96c16e..03d52a7f8 100644 --- a/src/nootka.qrc +++ b/src/nootka.qrc @@ -16,7 +16,6 @@ <file alias="Clef.qml">qml/score/Clef.qml</file> <file alias="KeySignature.qml">qml/score/KeySignature.qml</file> <file alias="Meter.qml">qml/score/Meter.qml</file> - <file alias="NoteSegment.qml">qml/score/NoteSegment.qml</file> <file alias="TaboutNootka.qml">qml/about/TaboutNootka.qml</file> <file alias="AboutPage.qml">qml/about/AboutPage.qml</file> diff --git a/src/qml/MainWindow.qml b/src/qml/MainWindow.qml index 95e03fdf8..433297acf 100644 --- a/src/qml/MainWindow.qml +++ b/src/qml/MainWindow.qml @@ -76,8 +76,13 @@ ApplicationWindow { id: score Layout.fillWidth: true Layout.fillHeight: true + Component.onCompleted: { + for (var n = 1; n < 8; ++n) + addNote(Noo.note(1 + Math.random() * 7, -2 + Math.random() * 5, Math.min(Math.max(-2, -3 + Math.random() * 6), 2))) + } } + // space for an instrument Rectangle { height: nootkaWindow.height / 4; Layout.fillWidth: true; color: activPal.window; border { width: 1; color: activPal.text } } } diff --git a/src/qml/score/NoteSegment.qml b/src/qml/score/NoteSegment.qml index 9ecce8285..4e2bab6bd 100644 --- a/src/qml/score/NoteSegment.qml +++ b/src/qml/score/NoteSegment.qml @@ -19,6 +19,8 @@ import QtQuick 2.7 import QtQuick.Controls 2.0 +import Score 1.0 + Item { id: noteSegment @@ -26,40 +28,76 @@ Item { height: parent.height width: 7 - property real notePos: 0 + property TnoteObject noteObj: null property color color: activPal.text + onNoteObjChanged: noteObj.changed.connect(update) + + Text { + id: head + font { family: "Scorek"; pixelSize: 7 } + y: noteObj.notePosY - 15 + color: noteSegment.color + visible: noteObj.notePosY > 0 + } + Text { - id: noteHead + id: alter font { family: "Scorek"; pixelSize: 7 } - y: notePos - staff.upperLine - text: "\ue1d5" + y: noteObj.notePosY - 15 color: noteSegment.color - visible: notePos > 0 + visible: noteObj.notePosY > 0 + x: head.x - width - 0.1 + } + + Rectangle { + id: stem + width: 0.3 + height: 6 + color: activPal.text + visible: noteObj.stemVisible() + } + + Text { + id: flag + font { family: "Scorek"; pixelSize: 7 } + color: activPal.text + x: stem.x + 0.1 + y: stem.y - 15 } Repeater { // upper lines - id: upRep model: 7 Rectangle { - x: noteHead.x - 0.5 + x: head.x - 0.5 y: 2 * (index + 1) - 0.1 - height: 0.18 + height: 0.2 width: 3.5 color: noteSegment.color - visible: notePos > 0 && (index) >= Math.floor(notePos / 2) - 1 + visible: noteObj.notePosY > 0 && index >= Math.floor((noteObj.notePosY - 1) / 2) } } - Repeater { // upper lines - id: lowRep - model: (staff.height - staff.upperLine - 12) / 2 + Repeater { // lower lines + model: (staff.height - noteObj.upperLinePos() - 12) / 2 Rectangle { - x: noteHead.x - 0.5 - y: staff.upperLine + 9.9 + 2 * index - height: 0.18 + x: head.x - 0.5 + y: noteObj.upperLinePos() + 10.0 + 2 * index - 0.1 + height: 0.2 width: 3.5 color: noteSegment.color - visible: staff.upperLine + 10 + index * 2 <= notePos - 1 + visible: noteObj.upperLinePos() + 10 + index * 2 <= noteObj.notePosY } } + + function update() { + alter.text = noteObj.alter() + head.text = noteObj.head() + stem.visible = noteObj.stemVisible() + if (noteObj.stemVisible()) { + stem.x = noteObj.stemDown() ? head.x : head.x + 2.0 + stem.y = noteObj.notePosY - (noteObj.stemDown() ? 0 : stem.height) + flag.y = noteObj.stemDown() ? stem.y - stem.height - 3 : stem.y - 15 + } + flag.text = noteObj.flag() + } } diff --git a/src/qml/score/Score.qml b/src/qml/score/Score.qml index dab880b13..5d84aba93 100644 --- a/src/qml/score/Score.qml +++ b/src/qml/score/Score.qml @@ -25,6 +25,8 @@ import Score 1.0 Flickable { id: score + TscoreObject { id: scoreObj; /*parent: score*/ } + property int clef: Tclef.Treble_G_8down property int meter: Tmeter.Meter_4_4 property alias bgColor: bgRect.color @@ -71,4 +73,7 @@ Flickable { staff0.enableKeySignature(enableKeySign) } + function addNote(n) { + scoreObj.addNote(n) + } } diff --git a/src/qml/score/Staff.qml b/src/qml/score/Staff.qml index e1de8bdb3..dc2858006 100644 --- a/src/qml/score/Staff.qml +++ b/src/qml/score/Staff.qml @@ -29,7 +29,6 @@ Item { property real linesCount: 40 property int number: -1 - property real upperLine: 16.0 property KeySignature keySignature: null property Meter meter: null property real firstNoteX: clef.width + (keySignature ? keySignature.width : 0) + (meter ? meter.width : 0) + 1 @@ -39,12 +38,14 @@ Item { scale: score.height / linesCount transformOrigin: Item.TopLeft + TstaffObject { id: staffObj; score: scoreObj; staffItem: staff; notesIndent: firstNoteX } + Repeater { // staff lines model: 5 Rectangle { x: 0.5 - y: upperLine + 2 * index - 0.1 - height: 0.18 + y: staffObj.upperLine + 2 * index - 0.1 + height: 0.2 width: staff.width - 1.0 color: activPal.text } @@ -86,13 +87,13 @@ Item { } } - Repeater { - model: 8 - NoteSegment { - notePos: upperLine + 11 - index - x: firstNoteX + index * width - } - } +// Repeater { +// model: 8 +// NoteSegment { +// notePos: upperLine + 11// - index +// x: firstNoteX //+ index * width +// } +// } function updateMeterPos() { meter.x = keySignature.x + keySignature.width -- GitLab