Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • seelook/nootka
  • lucas-marques/nootka
2 results
Show changes
Commits on Source (20)
Showing
with 277 additions and 126 deletions
name: Deploying
on:
push:
paths-ignore:
- '**.md'
env:
# VERSION: "3.0.6"
QT_VERSION_LINUX: 6.8.2
# QT_VERSION_MACOS: 6.8.1
# QT_VERSION_WINDOWS: 6.8.1
EXECUTABLE: "Nootka"
APPLICATION: "Nootka"
UNIXNAME: "nootka"
QML_DIR: "../../src/qml"
PUBLISHER: "Tom Seelook"
DESCRIPTION: "Application to learn how to play from sheet music"
QT_MODULES: qt5compat
jobs:
build-linux-x86_64:
runs-on: ubuntu-22.04
name: 'Linux (x86_64)'
steps:
- name: 'Checkout'
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set variables
run: |
VER=$(cat src/libs/core/nootkaconfig.h | awk -F" " '{ print $3 }' | sed 's/\"//g')
echo "NOOTKA_VERSION=$VER" >> $GITHUB_ENV
CNT=$(git rev-list HEAD --count)
echo "NOOTKA_COM_CNT=$CNT" >> $GITHUB_ENV
- name: 'Install Qt'
uses: jurplel/install-qt-action@v4
with:
version: ${{env.QT_VERSION_LINUX}}
modules: ${{env.QT_MODULES}}
cache: true
install-deps: 'true'
- name: 'Install dependencies'
run: |
sudo apt-get update
sudo apt-get install -y mesa-common-dev libsoundtouch-dev libfftw3-dev libasound2-dev libogg-dev libvorbis-dev libpulse-dev libjack-dev rsync git
sudo apt-get install -y libgl1-mesa-dev libxkbcommon-x11-0 rpm libfuse2 fakeroot
- name: 'Install CMake'
uses: lukka/get-cmake@latest
with:
useLocalCache: true
- name: 'Configure with CMake'
run: |
export QMAKE=/home/runner/work/${{env.EXECUTABLE}}/Qt/${{env.QT_VERSION_LINUX}}/gcc_64/bin/qmake
export PATH=/home/runner/work/${{env.EXECUTABLE}}/Qt/${{env.QT_VERSION_LINUX}}/gcc_64/libexec:$PATH
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DQT_QMAKE_EXECUTABLE=/home/runner/work/${{env.EXECUTABLE}}/Qt/${{env.QT_VERSION_LINUX}}/gcc_64/bin/qmake ../
- name: 'Build application'
run: |
cd build
cmake --build . --config Release -j 16
- name: 'Create AppImage'
run: |
cd "build/src"
wget https://github.com/dantti/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
wget https://github.com/dantti/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
chmod +x linuxdeploy-x86_64.AppImage
chmod +x linuxdeploy-plugin-qt-x86_64.AppImage
export QML_SOURCES_PATHS="${{env.QML_DIR}}"
export QMAKE=/home/runner/work/${{env.EXECUTABLE}}/Qt/${{env.QT_VERSION_LINUX}}/gcc_64/bin/qmake
export PATH=/home/runner/work/${{env.EXECUTABLE}}/Qt/${{env.QT_VERSION_LINUX}}/gcc_64/libexec:$PATH
./linuxdeploy-x86_64.AppImage --appdir AppDir -e ${{env.UNIXNAME}} -i ../../picts/${{env.UNIXNAME}}.png -d ../../mime/${{env.UNIXNAME}}.desktop --plugin qt --output appimage
rm linuxdeploy-x86_64.AppImage
rm linuxdeploy-plugin-qt-x86_64.AppImage
mv *.AppImage ../../${{env.EXECUTABLE}}-${{ env.NOOTKA_VERSION }}-b${{ env.NOOTKA_COM_CNT }}-Linux-x86_64.AppImage
- name: 'Upload artifact: AppImage'
uses: actions/upload-artifact@v4
with:
name: ${{env.EXECUTABLE}}-${{env.VERSION}}-Linux-x86_64.AppImage
path: ${{env.EXECUTABLE}}-${{env.VERSION}}-Linux-x86_64.AppImage
......@@ -78,3 +78,11 @@ Thumbs.db
*CMakeLists.txt.user
*android.iml
*qmlls.ini
*clang-format
*clangd
# VS code
.vscode*
.cache*
/build*/
......@@ -100,8 +100,8 @@ message(STATUS "
")
find_package(Qt5Core)
get_target_property(QtCore_location_Release Qt5::Core LOCATION_Release)
find_package(Qt6Core)
get_target_property(QtCore_location_Release Qt6::Core LOCATION_Release)
get_filename_component(QT_BINARY_DIR "${QtCore_location_Release}" DIRECTORY)
if(WIN32)
......@@ -121,11 +121,11 @@ if(WIN32)
add_custom_target(runinplace
COMMAND echo
COMMAND echo Copying libraries...
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_BINARY_DIR}/Qt5Core.dll ${CMAKE_BINARY_DIR}/src/.
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_BINARY_DIR}/Qt5Gui.dll ${CMAKE_BINARY_DIR}/src/.
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_BINARY_DIR}/Qt5Widgets.dll ${CMAKE_BINARY_DIR}/src/.
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_BINARY_DIR}/Qt5Network.dll ${CMAKE_BINARY_DIR}/src/.
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_BINARY_DIR}/Qt5PrintSupport.dll ${CMAKE_BINARY_DIR}/src/.
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_BINARY_DIR}/Qt6Core.dll ${CMAKE_BINARY_DIR}/src/.
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_BINARY_DIR}/Qt6Gui.dll ${CMAKE_BINARY_DIR}/src/.
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_BINARY_DIR}/Qt6Widgets.dll ${CMAKE_BINARY_DIR}/src/.
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_BINARY_DIR}/Qt6Network.dll ${CMAKE_BINARY_DIR}/src/.
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_BINARY_DIR}/Qt6PrintSupport.dll ${CMAKE_BINARY_DIR}/src/.
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/src/plugins/platforms
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_BINARY_DIR}/../plugins/platforms/qwindows.dll ${CMAKE_BINARY_DIR}/src/plugins/platforms/.
......
......@@ -9,6 +9,7 @@ qt_standard_project_setup(REQUIRES 6.5)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(QT_QML_GENERATE_QMLLS_INI ON)
if(UNIX AND NOT APPLE)
if (PACKAGE_ARCHITECTURE MATCHES "arm" OR PACKAGE_ARCHITECTURE MATCHES "aarch64")
......@@ -151,6 +152,9 @@ include_directories( core/music core/score )
qt_add_qml_module(nootka
URI "Nootka.Music"
SOURCES
core/taction.cpp
core/taction.h
core/music/tnote.h
core/music/tnote.cpp
core/music/trhythm.h
......@@ -184,6 +188,8 @@ qt_add_qml_module(nootka
core/score/tmelodypreview.h
core/score/tdummychord.cpp
core/score/tdummychord.h
DEPENDENCIES
QtQuick
)
# qmlRegisterUncreatableType<TmelodyPart>("Score", 1, 0, "TmelodyPart", QStringLiteral("You cannot create an instance of the TcommonInstrument."));
......
......@@ -49,7 +49,7 @@ set(LIB_NOOTKACORE_SRC
tpath.cpp
tmtr.cpp
tnootkaqml.cpp
taction.cpp
# taction.cpp
tnoofont.cpp
minizip/tzip.cpp
......
......@@ -437,12 +437,14 @@ void TmeasureObject::changeNoteDuration(TnotePair *np, const Tnote &newNote)
}
}
np->setPairNotes(nn);
score()->updateNoteInList(np, nn);
update(np->rhythmGroup());
checkBarLine();
} else { // measure duration is less than meter - take notes from the next measure
m_free += prevDur - newDur;
np->setPairNotes(nn);
score()->updateNoteInList(np, nn);
fill(); // it updates measure
}
shiftReleased(notesToOut);
......@@ -523,7 +525,9 @@ int TmeasureObject::releaseAtEnd(int dur, Tpairs &notesToOut, int endNote)
rList[r].setTie(Trhythm::e_tieCont);
m_score->insertSilently(lastNote->index() + r, Tnote(*lastNote->note(), rList[r]), this);
}
lastNote->setPairNotes(Tnote(*lastNote->note(), rList.first()));
Tnote n(Tnote(*lastNote->note(), rList.first()));
lastNote->setPairNotes(n);
score()->updateNoteInList(lastNote, n);
// remaining part of the note that goes to next measure
auto rtmToNext = Trhythm::resolve(dur);
int indexToInsert = rtmToNext.count() > 1 ? 0 : notesToOut.count();
......@@ -563,7 +567,9 @@ void TmeasureObject::releaseAtStart(int dur, Tpairs &notesToOut)
firstTie = firstNote->note()->rtm.tie();
if (!firstNote->note()->isRest())
rList.first().setTie(firstTie > Trhythm::e_tieStart ? Trhythm::e_tieCont : Trhythm::e_tieEnd);
firstNote->setPairNotes(Tnote(*firstNote->note(), rList.first()));
Tnote n(Tnote(*firstNote->note(), rList.first()));
firstNote->setPairNotes(n);
score()->updateNoteInList(firstNote, n);
for (int r = 1; r < rList.count(); ++r) {
if (!firstNote->note()->isRest())
rList[r].setTie(Trhythm::e_tieCont);
......@@ -606,7 +612,7 @@ void TmeasureObject::releaseAtStart(int dur, Tpairs &notesToOut)
void TmeasureObject::insertSilently(int id, TnotePair *np)
{
m_notes.insert(id, np);
m_notes.insert(qBound(0, id, m_notes.size()), np);
if (np->item() == nullptr)
np->setNoteItem(new TnoteItem(m_staff, np));
else if (m_staff != np->item()->staff())
......
......@@ -227,7 +227,7 @@ void TnoteItem::setNote(const Tnote &n)
if (oldNotePos != static_cast<int>(m_notePosY)) {
if (m_notePosY) {
m_head->setVisible(true);
m_head->setY(m_notePosY - 15.0);
m_head->setY(m_notePosY - 14.0);
} else
m_head->setVisible(false);
......@@ -485,6 +485,7 @@ void TnoteItem::setStringNumber(int strNr)
}
if (strNr > 0 && strNr < 7) {
m_stringNumber->setProperty("text", QString::number(strNr));
m_stringNumber->setProperty("color", qApp->palette().text());
m_stringNumber->setX((width() - m_stringNumber->width()) / 2.0);
// TODO set Y position
m_stringNumber->setVisible(true);
......@@ -735,14 +736,14 @@ void TnoteItem::hoverMoveEvent(QHoverEvent *event)
void TnoteItem::mousePressEvent(QMouseEvent *event)
{
if (!m_staff->score()->readOnly() && (m_staff->score()->singleNote() || m_staff->score()->editMode())) {
if (event->button() == Qt::LeftButton && event->pos().y() > 2.0 && event->pos().y() < height()) {
if (event->button() == Qt::LeftButton && event->position().y() > 2.0 && event->position().y() < height()) {
setKeepMouseGrab(true);
m_measure->score()->setPressedNote(this);
if (m_measure->score()->activeNote() != this) {
m_measure->score()->changeActiveNote(this);
m_measure->score()->setActiveNotePos(qFloor(event->pos().y()));
m_measure->score()->setActiveNotePos(qFloor(event->position().y()));
} else if (m_staff->score()->singleNote())
m_measure->score()->setActiveNotePos(qFloor(event->pos().y()));
m_measure->score()->setActiveNotePos(qFloor(event->position().y()));
if (!m_measure->score()->hoveredNote()) {
m_measure->score()->touchHideTimer()->stop();
......@@ -767,7 +768,7 @@ void TnoteItem::mouseReleaseEvent(QMouseEvent *event)
if (event->button() == Qt::LeftButton) {
if (keepMouseGrab())
setKeepMouseGrab(false);
if (event->pos().y() > 2.0 && event->pos().y() < height()) {
if (event->position().y() > 2.0 && event->position().y() < height()) {
if (m_measure->score()->hoveredNote()) { // mouse
if (m_measure->score()->hoveredNote() == this)
m_measure->score()->noteClicked(m_measure->score()->activeYpos());
......
......@@ -110,6 +110,7 @@ void TscoreObject::setClefType(Tclef::EclefType ct)
newNote.rtm.setStemDown(false);
noteSeg->item()->setStemHeight(STEM_HEIGHT);
noteSeg->setPairNotes(newNote);
updateNoteInList(noteSeg, newNote);
} else {
Tnote newNote(*noteSeg->note());
if (oldClef == Tclef::NoClef) {
......@@ -132,6 +133,7 @@ void TscoreObject::setClefType(Tclef::EclefType ct)
}
noteSeg->setPairNotes(newNote);
updateNoteInList(noteSeg, newNote);
if (pianoChanged) {
int nextRtmGr = (n == notesCount() - 1 ? -1 : m_segments[n + 1]->rhythmGroup());
......@@ -307,105 +309,109 @@ void TscoreObject::addNote(const Tnote &newNote, bool fromQML)
void TscoreObject::setNote(TnoteItem *no, const Tnote &n)
{
if (no) {
if (m_allowAdding && m_meter->meter() != Tmeter::NoMeter && no == lastNote() && no->note()->rtm != n.rtm) {
deleteLastNote();
addNote(n);
emitLastNote();
return;
}
if (!no)
return;
int durDiff = no->note()->duration() - n.duration();
if (m_allowAdding && m_meter->meter() != Tmeter::NoMeter && no == lastNote() && no->note()->rtm != n.rtm) {
deleteLastNote();
addNote(n);
emitLastNote();
return;
}
auto oldNote = *no->wrapper()->note();
auto newNote = n;
if (!durDiff) {
newNote.rtm.setBeam(oldNote.rtm.beam());
newNote.rtm.setTie(oldNote.rtm.tie());
}
fitToRange(newNote);
bool fitStaff = false;
// disconnect tie (if any) if note pitch changed
QPoint notesForAlterCheck; // x is first note and y is the last note to check
if (oldNote.rtm.tie() && newNote.chromatic() != oldNote.chromatic()) {
// alters of notes has to be checked due to note changed
// and all measures contained note with the tie are affected. Find them then
notesForAlterCheck = tieRange(no);
notesForAlterCheck.setX(m_segments[notesForAlterCheck.x()]->item()->measure()->firstNoteId());
notesForAlterCheck.setY(m_segments[notesForAlterCheck.y()]->item()->measure()->lastNoteId());
if (oldNote.rtm.tie() == Trhythm::e_tieStart) {
int durDiff = no->note()->duration() - n.duration();
auto oldNote = *no->wrapper()->note();
auto newNote = n;
if (!durDiff) {
newNote.rtm.setBeam(oldNote.rtm.beam());
newNote.rtm.setTie(oldNote.rtm.tie());
}
fitToRange(newNote);
bool fitStaff = false;
// disconnect tie (if any) if note pitch changed
QPoint notesForAlterCheck; // x is first note and y is the last note to check
if (oldNote.rtm.tie() && newNote.chromatic() != oldNote.chromatic()) {
// alters of notes has to be checked due to note changed
// and all measures contained note with the tie are affected. Find them then
notesForAlterCheck = tieRange(no);
notesForAlterCheck.setX(m_segments[notesForAlterCheck.x()]->item()->measure()->firstNoteId());
notesForAlterCheck.setY(m_segments[notesForAlterCheck.y()]->item()->measure()->lastNoteId());
if (oldNote.rtm.tie() == Trhythm::e_tieStart) {
m_segments[no->index() + 1]->disconnectTie(TnotePair::e_untieNext);
} else { // tie continue or end
if (oldNote.rtm.tie() == Trhythm::e_tieCont)
m_segments[no->index() + 1]->disconnectTie(TnotePair::e_untieNext);
} else { // tie continue or end
if (oldNote.rtm.tie() == Trhythm::e_tieCont)
m_segments[no->index() + 1]->disconnectTie(TnotePair::e_untieNext);
m_segments[no->index() - 1]->disconnectTie(TnotePair::e_untiePrev);
}
newNote.rtm.setTie(Trhythm::e_noTie);
if (no->wrapper() == no->staff()->firstNote())
no->staff()->deleteExtraTie();
fitStaff = true;
m_segments[no->index() - 1]->disconnectTie(TnotePair::e_untiePrev);
}
newNote.rtm.setTie(Trhythm::e_noTie);
if (no->wrapper() == no->staff()->firstNote())
no->staff()->deleteExtraTie();
fitStaff = true;
}
if (durDiff) {
no->measure()->changeNoteDuration(no->wrapper(), newNote);
if (lastMeasure()->isEmpty())
removeLastMeasure();
adjustScoreWidth();
} else {
no->wrapper()->setPairNotes(newNote);
// When note or alter are different - check accidentals in whole measure and fit staff if necessary
if (!notesForAlterCheck.isNull() || oldNote.note() != newNote.note() || oldNote.alter() != newNote.alter()) {
if (notesForAlterCheck.isNull())
notesForAlterCheck = QPoint(no->measure()->firstNoteId(), no->measure()->lastNoteId());
auto measureToRefresh = m_segments[notesForAlterCheck.x()]->item()->measure();
for (int n = notesForAlterCheck.x(); n <= notesForAlterCheck.y(); ++n) {
if (m_segments[n]->note()->note() == oldNote.note() || m_segments[n]->note()->note() == newNote.note()) {
fitStaff = true;
m_segments[n]->item()->updateAlter();
}
// Update measure sums (notes width)
if (m_segments[n]->item()->measure() != measureToRefresh) {
measureToRefresh->refresh();
measureToRefresh = m_segments[n]->item()->measure();
}
if (durDiff) {
no->measure()->changeNoteDuration(no->wrapper(), newNote);
if (lastMeasure()->isEmpty())
removeLastMeasure();
adjustScoreWidth();
} else {
no->wrapper()->setPairNotes(newNote);
updateNoteInList(no->wrapper(), newNote);
// When note or alter are different - check accidentals in whole measure and fit staff if necessary
if (!notesForAlterCheck.isNull() || oldNote.note() != newNote.note() || oldNote.alter() != newNote.alter()) {
if (notesForAlterCheck.isNull())
notesForAlterCheck = QPoint(no->measure()->firstNoteId(), no->measure()->lastNoteId());
auto measureToRefresh = m_segments[notesForAlterCheck.x()]->item()->measure();
for (int n = notesForAlterCheck.x(); n <= notesForAlterCheck.y(); ++n) {
if (m_segments[n]->note()->note() == oldNote.note() || m_segments[n]->note()->note() == newNote.note()) {
fitStaff = true;
m_segments[n]->item()->updateAlter();
}
// Update measure sums (notes width)
if (m_segments[n]->item()->measure() != measureToRefresh) {
measureToRefresh->refresh();
measureToRefresh = m_segments[n]->item()->measure();
}
measureToRefresh->refresh();
}
// update note range on current staff
if (oldNote.note() != newNote.note() || oldNote.octave() != newNote.octave())
no->staff()->checkNotesRange();
// If there is a beam - prepare it again then draw
if (no->wrapper()->beam()) {
no->wrapper()->beam()->prepareBeam();
if (!fitStaff)
no->wrapper()->beam()->drawBeam();
}
if (fitStaff) {
m_segments[notesForAlterCheck.x()]->item()->staff()->fit();
if (m_segments[notesForAlterCheck.y()]->item()->staff() != m_segments[notesForAlterCheck.x()]->item()->staff())
m_segments[notesForAlterCheck.y()]->item()->staff()->fit();
}
measureToRefresh->refresh();
}
if (no == m_selectedItem)
emit selectedNoteChanged();
if (m_singleNote && m_enharmNotesEnabled && n.isValid()) {
TnotesList enharmList = newNote.getTheSameNotes(m_enableDoubleAccids);
TnotesList::iterator it = enharmList.begin();
++it;
if (it != enharmList.end()) {
note(1)->setVisible(true);
m_segments[1]->setPairNotes(*(it));
} else
note(1)->setVisible(false);
++it;
if (it != enharmList.end()) {
note(2)->setVisible(true);
m_segments[2]->setPairNotes(*(it));
} else
note(2)->setVisible(false);
// update note range on current staff
if (oldNote.note() != newNote.note() || oldNote.octave() != newNote.octave())
no->staff()->checkNotesRange();
// If there is a beam - prepare it again then draw
if (no->wrapper()->beam()) {
no->wrapper()->beam()->prepareBeam();
if (!fitStaff)
no->wrapper()->beam()->drawBeam();
}
if (fitStaff) {
m_segments[notesForAlterCheck.x()]->item()->staff()->fit();
if (m_segments[notesForAlterCheck.y()]->item()->staff() != m_segments[notesForAlterCheck.x()]->item()->staff())
m_segments[notesForAlterCheck.y()]->item()->staff()->fit();
}
}
if (no == m_selectedItem)
emit selectedNoteChanged();
if (m_singleNote && m_enharmNotesEnabled && n.isValid()) {
TnotesList enharmList = newNote.getTheSameNotes(m_enableDoubleAccids);
TnotesList::iterator it = enharmList.begin();
++it;
if (it != enharmList.end()) {
note(1)->setVisible(true);
m_segments[1]->setPairNotes(*(it));
updateNoteInList(m_segments[1], *(it));
} else
note(1)->setVisible(false);
++it;
if (it != enharmList.end()) {
note(2)->setVisible(true);
m_segments[2]->setPairNotes(*(it));
updateNoteInList(m_segments[2], *(it));
} else
note(2)->setVisible(false);
}
}
void TscoreObject::setNote(int noteNr, const Tnote &n)
......@@ -780,6 +786,7 @@ void TscoreObject::transpose(int semis, bool outScaleToRest, const Tnote &loNote
}
noteSeg->setPairNotes(transposed);
updateNoteInList(noteSeg, transposed);
if (noteSeg->beam() && !transRtm.isRest())
fixBeam = true;
......@@ -1324,6 +1331,7 @@ void TscoreObject::checkTieOfSelected()
prevNote->disconnectTie(TnotePair::e_untiePrev);
n.rtm.setTie(n.rtm.tie() == Trhythm::e_tieEnd ? Trhythm::e_noTie : Trhythm::e_tieStart);
m_selectedItem->wrapper()->setPairNotes(n);
updateNoteInList(m_selectedItem->wrapper(), n);
emit m_selectedItem->hasTieChanged();
if (m_selectedItem->staff()->firstNote()->item() == m_selectedItem)
m_selectedItem->staff()->deleteExtraTie();
......@@ -1331,9 +1339,11 @@ void TscoreObject::checkTieOfSelected()
if (!m_selectedItem->note()->isRest() && m_selectedItem->note()->chromatic() == prevNote->note()->chromatic()) {
n.rtm.setTie(n.rtm.tie() == Trhythm::e_noTie ? Trhythm::e_tieEnd : Trhythm::e_tieCont);
m_selectedItem->wrapper()->setPairNotes(n);
updateNoteInList(m_selectedItem->wrapper(), n);
auto pn = *prevNote->note();
pn.rtm.setTie(pn.rtm.tie() == Trhythm::e_noTie ? Trhythm::e_tieStart : Trhythm::e_tieCont);
prevNote->setPairNotes(pn);
updateNoteInList(prevNote, pn);
emit m_selectedItem->hasTieChanged();
if (m_selectedItem->staff()->firstNote()->item() == m_selectedItem)
m_selectedItem->staff()->createExtraTie(m_selectedItem);
......@@ -1689,6 +1699,18 @@ bool TscoreObject::removeLastMeasure()
return adjust;
}
void TscoreObject::updateNoteInList(TnotePair *segment, const Tnote &n)
{
int cnt = 0;
for (auto *const s : std::as_const(m_segments)) {
if (s == segment) {
m_notes[cnt] = n;
break;
}
cnt++;
}
}
// Tnote dummyNote;
// CHECKTIME (
// for (int n = 0; n < 200; ++n) {
......
......@@ -640,6 +640,14 @@ protected:
*/
TnotePair *insertSilently(int id, const Tnote &n, TmeasureObject *m = nullptr);
/**
* Looks for index of @p segment in @p m_segments
* and sets @p m_notes list if that index to @p n note.
* It is required due to @p TnotePair keeps note
* independently from @p m_notes
*/
void updateNoteInList(TnotePair *segment, const Tnote &n);
private:
/**
* Appends notes to @p m_notes list, creates corresponding @p TnotePair
......
......@@ -19,9 +19,10 @@
#ifndef TACTION_H
#define TACTION_H
#include "nootkacoreglobal.h"
#include <QtCore/qobject.h>
#include <QtGui/qcolor.h>
#include <nootkacoreglobal.h>
#include <QtQml/qqmlregistration.h>
class QQmlComponent;
......@@ -35,6 +36,7 @@ class QQmlComponent;
class NOOTKACORE_EXPORT Taction : public QObject
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(QString icon READ icon WRITE setIconTag NOTIFY iconChanged)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
......
......@@ -79,7 +79,6 @@ TnootkaQML::TnootkaQML(QObject *parent)
qmlRegisterType<TpianoBg>("Nootka", 1, 0, "TpianoBg");
qmlRegisterType<TbandoneonBg>("Nootka", 1, 0, "TbandoneonBg");
qmlRegisterType<TsaxBg>("Nootka", 1, 0, "TsaxBg");
qmlRegisterType<Taction>("Nootka", 1, 0, "Taction");
qmlRegisterUncreatableType<TnootkaQML>("Nootka", 1, 0, "Nootka", QStringLiteral("You cannot create an instance of the TnootkaQML."));
qmlRegisterType<TtuneObject>("Nootka", 1, 0, "TtuneObject");
......
......@@ -16,17 +16,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "core/tglobals.h"
#include "core/tinitcorelib.h"
#include "core/tmtr.h"
#include "core/tnootkaqml.h"
#include "core/tpath.h"
#include "dialogs/tdialogloaderobject.h"
#include "help/tmainhelp.h"
#include "main/tgotit.h"
#include "main/tmainscoreobject.h"
#include "main/tnameitem.h"
#include <tglobals.h>
#include <tinitcorelib.h>
#include <tmtr.h>
#include <tnootkaqml.h>
#include <tpath.h>
#include <tsound.h>
#include "sound/tsound.h"
#if defined(Q_OS_ANDROID)
#include "mobile/tmobilemenu.h"
......
......@@ -3,6 +3,7 @@
* on the terms of GNU GPLv3 license (http://www.gnu.org/licenses) */
import Nootka 1.0
import Nootka.Music
import QtQuick 2.12
import QtQuick.Controls 2.12
......
......@@ -3,6 +3,7 @@
* on the terms of GNU GPLv3 license (http://www.gnu.org/licenses) */
import Nootka 1.0
import Nootka.Music
import Qt5Compat.GraphicalEffects
import QtQuick 2.12
import QtQuick.Controls 2.12
......
......@@ -4,7 +4,7 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import Nootka.Music
import Nootka 1.0
......
......@@ -108,7 +108,7 @@ Dialog {
nootkaWindow.executor.init(1, examFile);
close();
}
onOpenLevel: {
onOpenLevel: levelFile => {
page = Nootka.LevelCreator;
currentDialog.openLevel(levelFile);
}
......
......@@ -178,7 +178,7 @@ ApplicationWindow {
examResults.destroy();
}
}
function onWantOpenFile() : void {
function onWantOpenFile(fileName: string) : void {
showDialog(Nootka.NoDialog);
dialogLoader.openFile(fileName);
}
......
......@@ -4,6 +4,7 @@
import "../"
import Nootka 1.0
import Nootka.Music
import QtQuick 2.12
import QtQuick.Controls 2.12
......
......@@ -18,22 +18,22 @@ Text {
switch (score.clef) {
case Tclef.Treble_G:
case Tclef.Treble_G_8down:
y = 5;
y = 6;
break;
case Tclef.Bass_F:
case Tclef.Bass_F_8down:
case Tclef.Tenor_C:
y = 1;
y = 2;
break;
case Tclef.Alto_C:
y = 3;
y = 4;
break;
case Tclef.PianoStaffClefs:
y = 3;
y = 4;
x = 3;
break;
case Tclef.NoClef:
y = 3;
y = 4;
x = 2;
break;
}
......@@ -41,7 +41,7 @@ Text {
width: 5.5
x: 0.5
y: 5
y: 4
text: NOO.clef(score.clef).glyph()
color: clefArea.containsMouse && (GLOB.singleNoteMode || scoreObj.editMode) ? GLOB.noteCursorColor : activPal.text
Component.onCompleted: getPos()
......@@ -84,14 +84,14 @@ Text {
font: clef.font
text: "\ue062"
color: clef.color
y: clef.y + 15
y: clef.y + 16
}
}
Connections {
target: score
function onClefChanged() : void { getPos() }
function onClefChanged() : void { getPos(); }
}
}
......@@ -32,7 +32,7 @@ Item {
accidOff = 3;
break;
}
return accidOff;
return accidOff - 1;
}
function keyUp() {
......@@ -85,7 +85,10 @@ Item {
color: activPal.text
text: score.keySignature < 0 ? "\ue260" : (score.keySignature > 0 ? "\ue262" : "") // flat or sharp symbols
x: index * 1.8
y: parent.y + (score.keySignature < 0 ? flatPos[index] : sharpPos[index]) - accidOffset(score.clef) + (score.clef === Tclef.Tenor_C && score.keySignature > 0 && (index === 0 || index === 2) ? 7 : 0)
y: parent.y + (score.keySignature < 0
? flatPos[index]
: sharpPos[index]) - accidOffset(score.clef)
+ (score.clef === Tclef.Tenor_C && score.keySignature > 0 && (index === 0 || index === 2) ? 7 : 0)
opacity: index < Math.abs(score.keySignature) ? 1 : 0
font {
......