Skip to content

Commit

Permalink
Merge pull request #5224 from DLLarson/qml-expose-noteevents
Browse files Browse the repository at this point in the history
Fix #291708 Plugin: Expose NoteEvent's via QML Note interface.
  • Loading branch information
dmitrio95 committed Jul 29, 2019
2 parents 366ccb0 + b05c823 commit c25a17e
Show file tree
Hide file tree
Showing 16 changed files with 490 additions and 36 deletions.
1 change: 0 additions & 1 deletion libmscore/accidental.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ extern AccidentalVal sym2accidentalVal(SymId id);
} // namespace Ms

Q_DECLARE_METATYPE(Ms::AccidentalRole);
Q_DECLARE_METATYPE(Ms::AccidentalType);


#endif
Expand Down
34 changes: 34 additions & 0 deletions libmscore/chord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3542,4 +3542,38 @@ void Chord::layoutArticulations3(Slur* slur)
}
}

//---------------------------------------------------------
// getNoteEventLists
// Get contents of all NoteEventLists for all notes in
// the chord.
//---------------------------------------------------------

QList<NoteEventList> Chord::getNoteEventLists()
{
QList<NoteEventList> ell;
if (notes().empty())
return ell;
for (size_t i = 0; i < notes().size(); ++i) {
ell.append(NoteEventList(notes()[i]->playEvents()));
}
return ell;
}

//---------------------------------------------------------
// setNoteEventLists
// Set contents of all NoteEventLists for all notes in
// the chord.
//---------------------------------------------------------

void Chord::setNoteEventLists(QList<NoteEventList>& ell)
{
if (notes().empty())
return;
Q_ASSERT(ell.size() == notes().size());
for (size_t i = 0; i < ell.size(); i++) {
notes()[i]->setPlayEvents(ell[int(i)]);
}

}

}
8 changes: 2 additions & 6 deletions libmscore/chord.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ class LedgerLine;
class AccidentalState;

enum class TremoloChordType : char { TremoloSingle, TremoloFirstNote, TremoloSecondNote };
enum class PlayEventType : char {
Auto, // Play events for all notes are calculated by MuseScore.
User, // Some play events are modified by user. The events must be written into the mscx file.
InvalidUser // The user modified play events must be replaced by MuseScore generated ones on
// next recalculation. The actual play events must be saved on the undo stack.
};

//---------------------------------------------------------
// @@ Chord
Expand Down Expand Up @@ -194,6 +188,8 @@ class Chord final : public ChordRest {

PlayEventType playEventType() const { return _playEventType; }
void setPlayEventType(PlayEventType v) { _playEventType = v; }
QList<NoteEventList> getNoteEventLists();
void setNoteEventLists(QList<NoteEventList>& nel);

TremoloChordType tremoloChordType() const;

Expand Down
28 changes: 7 additions & 21 deletions libmscore/rendermidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2305,12 +2305,8 @@ void Score::createGraceNotesPlayEvents(const Fraction& tick, Chord* chord, int&
el.append(nel);
}

if (gc->playEventType() == PlayEventType::InvalidUser)
gc->score()->undo(new ChangeEventList(gc, el));
else if (gc->playEventType() == PlayEventType::Auto) {
for (int ii = 0; ii < int(nn); ++ii)
gc->notes()[ii]->setPlayEvents(el[ii]);
}
if (gc->playEventType() == PlayEventType::Auto)
gc->setNoteEventLists(el);
on += graceDuration;
}
if (na) {
Expand All @@ -2332,12 +2328,8 @@ void Score::createGraceNotesPlayEvents(const Fraction& tick, Chord* chord, int&
el.append(nel);
}

if (gc->playEventType() == PlayEventType::InvalidUser)
gc->score()->undo(new ChangeEventList(gc, el));
else if (gc->playEventType() == PlayEventType::Auto) {
for (int ii = 0; ii < int(nn); ++ii)
gc->notes()[ii]->setPlayEvents(el[ii]);
}
if (gc->playEventType() == PlayEventType::Auto)
gc->setNoteEventLists(el);
on += graceDuration1;
}
}
Expand Down Expand Up @@ -2384,15 +2376,9 @@ void Score::createPlayEvents(Chord* chord)
// render normal (and articulated) chords
//
QList<NoteEventList> el = renderChord(chord, gateTime, ontime, trailtime);
if (chord->playEventType() == PlayEventType::InvalidUser) {
chord->score()->undo(new ChangeEventList(chord, el));
}
else if (chord->playEventType() == PlayEventType::Auto) {
int n = int(chord->notes().size());
for (int i = 0; i < n; ++i)
chord->notes()[i]->setPlayEvents(el[i]);
}
// don’t change event list if type is PlayEventType::User
if (chord->playEventType() == PlayEventType::Auto)
chord->setNoteEventLists(el);
// don't change event list if type is PlayEventType::User
}

void Score::createPlayEvents(Measure* start, Measure* end)
Expand Down
24 changes: 22 additions & 2 deletions libmscore/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ enum class ElementType {
// AccidentalType
//---------------------------------------------------------
// NOTE: keep this in sync with with accList array

enum class AccidentalType : char {
///.\{
NONE,
Expand Down Expand Up @@ -468,6 +469,20 @@ constexpr bool operator& (FontStyle a1, FontStyle a2) {
return static_cast<bool>(static_cast<char>(a1) & static_cast<char>(a2));
}

//---------------------------------------------------------
// PlayEventType
/// Determines whether oranaments are automatically generated
/// when playing a score and whether the PlayEvents are saved
/// in the score file.
//---------------------------------------------------------

enum class PlayEventType : char {
///.\{
Auto, ///< Play events for all notes are calculated by MuseScore.
User, ///< Some play events are modified by user. Those events are written into the mscx file.
///.\}
};

//---------------------------------------------------------
// Tuplets
//---------------------------------------------------------
Expand All @@ -477,7 +492,6 @@ enum class TupletBracketType : char { AUTO_BRACKET, SHOW_BRACKET, SHOW_NO_BRACKE

#ifdef SCRIPT_INTERFACE
Q_ENUM_NS(ElementType)
Q_ENUM_NS(AccidentalType)
Q_ENUM_NS(Direction)
Q_ENUM_NS(GlissandoType)
Q_ENUM_NS(GlissandoStyle)
Expand All @@ -486,6 +500,8 @@ Q_ENUM_NS(SegmentType)
Q_ENUM_NS(Tid)
Q_ENUM_NS(Align)
Q_ENUM_NS(NoteType)
Q_ENUM_NS(PlayEventType)
Q_ENUM_NS(AccidentalType)
#endif

//hack: to force the build system to run moc on this file
Expand All @@ -502,10 +518,14 @@ extern void fillComboBoxDirection(QComboBox*);

} // namespace Ms

Q_DECLARE_METATYPE(Ms::Align)
Q_DECLARE_METATYPE(Ms::Align);

Q_DECLARE_METATYPE(Ms::Direction);

Q_DECLARE_METATYPE(Ms::NoteType);

Q_DECLARE_METATYPE(Ms::PlayEventType);

Q_DECLARE_METATYPE(Ms::AccidentalType);

#endif
49 changes: 46 additions & 3 deletions libmscore/undo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1899,6 +1899,46 @@ void ChangeNoteEvents::flip(EditData*)
*/
}

//---------------------------------------------------------
// ChangeNoteEventList::flip
//---------------------------------------------------------

void ChangeNoteEventList::flip(EditData*)
{
note->score()->setPlaylistDirty();
// Get copy of current list.
NoteEventList nel = note->playEvents();
// Replace current copy with new list.
note->setPlayEvents(newEvents);
// Save copy of replaced list.
newEvents = nel;
// Get a copy of the current playEventType.
PlayEventType petval = note->chord()->playEventType();
// Replace current setting with new setting.
note->chord()->setPlayEventType(newPetype);
// Save copy of old setting.
newPetype = petval;
}

//---------------------------------------------------------
// ChangeNoteEventList::flip
//---------------------------------------------------------

void ChangeChordPlayEventType::flip(EditData*)
{
chord->score()->setPlaylistDirty();
// Flips data between NoteEventList's.
size_t n = chord->notes().size();
for (size_t i = 0; i < n; ++i) {
Note* note = chord->notes()[i];
note->playEvents().swap(events[int(i)]);
}
// Flips PlayEventType between chord and undo.
PlayEventType curPetype = chord->playEventType();
chord->setPlayEventType(petype);
petype = curPetype;
}

//---------------------------------------------------------
// ChangeInstrument::flip
//---------------------------------------------------------
Expand Down Expand Up @@ -2212,9 +2252,12 @@ void ChangeNoteEvent::flip(EditData*)
NoteEvent e = *oldEvent;
*oldEvent = newEvent;
newEvent = e;

// TODO:
note->chord()->setPlayEventType(PlayEventType::User);
// Get a copy of the current playEventType.
PlayEventType petval = note->chord()->playEventType();
// Replace current setting with new setting.
note->chord()->setPlayEventType(newPetype);
// Save copy of old setting.
newPetype = petval;
}

//---------------------------------------------------------
Expand Down
37 changes: 36 additions & 1 deletion libmscore/undo.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "stafftype.h"
#include "cleflist.h"
#include "note.h"
#include "chord.h"
#include "drumset.h"
#include "rest.h"
#include "fret.h"
Expand Down Expand Up @@ -898,6 +899,39 @@ class ChangeNoteEvents : public UndoCommand {
UNDO_NAME("ChangeNoteEvents")
};

//---------------------------------------------------------
// ChangeNoteEventList
//---------------------------------------------------------

class ChangeNoteEventList : public UndoCommand {
Ms::Note* note;
NoteEventList newEvents;
PlayEventType newPetype;

void flip(EditData*) override;

public:
ChangeNoteEventList(Ms::Note* n, NoteEventList& ne) :
note(n), newEvents(ne), newPetype(PlayEventType::User) {}
UNDO_NAME("ChangeNoteEventList")
};

//---------------------------------------------------------
// ChangeChordPlayEventType
//---------------------------------------------------------

class ChangeChordPlayEventType : public UndoCommand {
Ms::Chord* chord;
Ms::PlayEventType petype;
QList<NoteEventList> events;

void flip(EditData*) override;

public:
ChangeChordPlayEventType(Chord* c, Ms::PlayEventType pet) : chord(c), petype(pet) { events = c->getNoteEventLists(); }
UNDO_NAME("ChangeChordPlayEventType")
};

//---------------------------------------------------------
// ChangeInstrument
// change instrument in an InstrumentChange element
Expand Down Expand Up @@ -1190,12 +1224,13 @@ class ChangeNoteEvent : public UndoCommand {
Note* note;
NoteEvent* oldEvent;
NoteEvent newEvent;
PlayEventType newPetype;

void flip(EditData*) override;

public:
ChangeNoteEvent(Note* n, NoteEvent* oe, const NoteEvent& ne)
: note(n), oldEvent(oe), newEvent(ne) {}
: note(n), oldEvent(oe), newEvent(ne), newPetype(PlayEventType::User) {}
UNDO_NAME("ChangeNoteEvent")
};

Expand Down
2 changes: 2 additions & 0 deletions mscore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ if (SCRIPT_INTERFACE)
plugin/api/excerpt.h
plugin/api/util.h
plugin/api/selection.h
plugin/api/playevent.h

plugin/api/enums.cpp
plugin/mscorePlugins.cpp plugin/pluginCreator.cpp plugin/pluginManager.cpp plugin/qmledit.cpp
Expand All @@ -68,6 +69,7 @@ if (SCRIPT_INTERFACE)
plugin/api/excerpt.cpp
plugin/api/util.cpp
plugin/api/selection.cpp
plugin/api/playevent.cpp
)

set (SCRIPT_UI
Expand Down
15 changes: 15 additions & 0 deletions mscore/plugin/api/elements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "elements.h"
#include "libmscore/property.h"
#include "libmscore/undo.h"

namespace Ms {
namespace PluginAPI {
Expand Down Expand Up @@ -69,6 +70,20 @@ void Note::setTpc(int val)
set(Pid::TPC2, val);
}

//---------------------------------------------------------
// Chord::setPlayEventType
//---------------------------------------------------------

void Chord::setPlayEventType(Ms::PlayEventType v)
{
// Only create undo operation if the value has changed.
if (v != chord()->playEventType())
{
chord()->score()->setPlaylistDirty();
chord()->score()->undo(new ChangeChordPlayEventType(chord(), v));
}
}

//---------------------------------------------------------
// wrap
/// \cond PLUGIN_API \private \endcond
Expand Down
Loading

0 comments on commit c25a17e

Please sign in to comment.