Plugin API: add basic API for access to Instruments and Channels
This commit is contained in:
parent
2216872a7f
commit
a11883241d
7 changed files with 562 additions and 0 deletions
|
@ -49,6 +49,9 @@ set(MODULE_SRC
|
|||
${CMAKE_CURRENT_LIST_DIR}/api/excerpt.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/api/excerpt.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/api/fraction.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/api/instrument.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/api/instrument.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/api/part.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/api/part.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/api/playevent.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/api/playevent.h
|
||||
|
|
164
src/plugins/api/instrument.cpp
Normal file
164
src/plugins/api/instrument.cpp
Normal file
|
@ -0,0 +1,164 @@
|
|||
//=============================================================================
|
||||
// MuseScore
|
||||
// Music Composition & Notation
|
||||
//
|
||||
// Copyright (C) 2020 MuseScore BVBA
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.
|
||||
//
|
||||
// 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, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//=============================================================================
|
||||
|
||||
#include "instrument.h"
|
||||
|
||||
#include "framework/midi_old/midipatch.h"
|
||||
#include "libmscore/part.h"
|
||||
#include "libmscore/score.h"
|
||||
#include "libmscore/undo.h"
|
||||
|
||||
namespace Ms {
|
||||
namespace PluginAPI {
|
||||
//---------------------------------------------------------
|
||||
// Channel::activeChannel
|
||||
//---------------------------------------------------------
|
||||
|
||||
Ms::Channel* Channel::activeChannel()
|
||||
{
|
||||
Ms::Score* score = _part->score();
|
||||
Ms::MasterScore* masterScore = score->masterScore();
|
||||
|
||||
if (masterScore->playbackScore() == score) {
|
||||
return masterScore->playbackChannel(_channel);
|
||||
}
|
||||
return _channel;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Channel::setMidiBankAndProgram
|
||||
//---------------------------------------------------------
|
||||
|
||||
void Channel::setMidiBankAndProgram(int bank, int program, bool setUserBankController)
|
||||
{
|
||||
Ms::Channel* ch = activeChannel();
|
||||
|
||||
MidiPatch patch;
|
||||
// other values are unused in ChangePatch command
|
||||
patch.synti = ch->synti();
|
||||
patch.bank = bank;
|
||||
patch.prog = program;
|
||||
|
||||
Ms::Score* score = _part->score();
|
||||
score->undo(new ChangePatch(score, ch, &patch));
|
||||
|
||||
if (setUserBankController) {
|
||||
score->undo(new SetUserBankController(ch, true));
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Channel::setMidiProgram
|
||||
//---------------------------------------------------------
|
||||
|
||||
void Channel::setMidiProgram(int prog)
|
||||
{
|
||||
prog = qBound(0, prog, 127);
|
||||
setMidiBankAndProgram(activeChannel()->bank(), prog, false);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Channel::setMidiBank
|
||||
//---------------------------------------------------------
|
||||
|
||||
void Channel::setMidiBank(int bank)
|
||||
{
|
||||
bank = qBound(0, bank, 255);
|
||||
setMidiBankAndProgram(bank, activeChannel()->program(), true);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// StringData::stringList
|
||||
//---------------------------------------------------------
|
||||
|
||||
QVariantList StringData::stringList() const
|
||||
{
|
||||
QVariantList pluginStringsList;
|
||||
for (instrString str : _data.stringList()) {
|
||||
QVariantMap pluginStringData;
|
||||
pluginStringData["pitch"] = str.pitch;
|
||||
pluginStringData["open"] = str.open;
|
||||
pluginStringsList.append(pluginStringData);
|
||||
}
|
||||
return pluginStringsList;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ChannelListProperty
|
||||
//---------------------------------------------------------
|
||||
|
||||
ChannelListProperty::ChannelListProperty(Instrument* i)
|
||||
: QQmlListProperty<Channel>(i, i, &count, &at) {}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ChannelListProperty::count
|
||||
//---------------------------------------------------------
|
||||
|
||||
int ChannelListProperty::count(QQmlListProperty<Channel>* l)
|
||||
{
|
||||
return static_cast<int>(static_cast<Instrument*>(l->data)->instrument()->channel().size());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ChannelListProperty::at
|
||||
//---------------------------------------------------------
|
||||
|
||||
Channel* ChannelListProperty::at(QQmlListProperty<Channel>* l, int i)
|
||||
{
|
||||
Instrument* instr = static_cast<Instrument*>(l->data);
|
||||
|
||||
if (i < 0 || i >= instr->instrument()->channel().size()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ms::Channel* ch = instr->instrument()->channel(i);
|
||||
|
||||
return customWrap<Channel>(ch, instr->part());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Instrument::longName
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Instrument::longName() const
|
||||
{
|
||||
const QList<Ms::StaffName>& names = instrument()->longNames();
|
||||
return names.empty() ? "" : names[0].name();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Instrument::shortName
|
||||
//---------------------------------------------------------
|
||||
|
||||
QString Instrument::shortName() const
|
||||
{
|
||||
const QList<Ms::StaffName>& names = instrument()->shortNames();
|
||||
return names.empty() ? "" : names[0].name();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Instrument::channels
|
||||
//---------------------------------------------------------
|
||||
|
||||
ChannelListProperty Instrument::channels()
|
||||
{
|
||||
return ChannelListProperty(this);
|
||||
}
|
||||
} // namespace PluginAPI
|
||||
} // namespace Ms
|
265
src/plugins/api/instrument.h
Normal file
265
src/plugins/api/instrument.h
Normal file
|
@ -0,0 +1,265 @@
|
|||
//=============================================================================
|
||||
// MuseScore
|
||||
// Music Composition & Notation
|
||||
//
|
||||
// Copyright (C) 2020 MuseScore BVBA
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.
|
||||
//
|
||||
// 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, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//=============================================================================
|
||||
|
||||
#ifndef __PLUGIN_API_INSTRUMENT_H__
|
||||
#define __PLUGIN_API_INSTRUMENT_H__
|
||||
|
||||
#include "scoreelement.h"
|
||||
#include "libmscore/instrument.h"
|
||||
|
||||
namespace Ms {
|
||||
class Instrument;
|
||||
|
||||
namespace PluginAPI {
|
||||
class Instrument;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Channel
|
||||
/// Provides an access to channel properties. Similar to
|
||||
/// Mixer, changes to some of the playback-related
|
||||
/// properties are not recorded to undo stack and are not
|
||||
/// revertable with standard user-visible "undo" action.
|
||||
/// Changing MIDI patch though is undoable in normal way
|
||||
/// ("dock" type plugins may need to call
|
||||
/// \ref Score.startCmd / \ref Score.endCmd for that to
|
||||
/// work properly).
|
||||
///
|
||||
/// Iterating over all channels in the current score can
|
||||
/// be done as follows:
|
||||
/// \code
|
||||
/// var parts = curScore.parts;
|
||||
/// for (var i = 0; i < parts.length; ++i) {
|
||||
/// var part = parts[i];
|
||||
/// var instrs = part.instruments;
|
||||
/// for (var j = 0; j < instrs.length; ++j) {
|
||||
/// var instr = instrs[j];
|
||||
/// var channels = instr.channels;
|
||||
/// for (var k = 0; k < channels.length; ++k) {
|
||||
/// var channel = channels[k];
|
||||
/// channel.volume = 64; // just for example, changing the channel's volume
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// \endcode
|
||||
/// \since MuseScore 3.5
|
||||
//---------------------------------------------------------
|
||||
|
||||
class Channel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Ms::Channel* _channel;
|
||||
Ms::Part* _part;
|
||||
|
||||
/** Name of this channel */
|
||||
Q_PROPERTY(QString name READ name)
|
||||
|
||||
/**
|
||||
* Channel volume, from 0 to 127.
|
||||
* \note Changing this property is **not** revertable with a standard "undo"
|
||||
* action. Plugins may need to handle reverting this property change if
|
||||
* necessary.
|
||||
*/
|
||||
Q_PROPERTY(int volume READ volume WRITE setVolume)
|
||||
/**
|
||||
* Channel pan, from 0 to 127.
|
||||
* \note Changing this property is **not** revertable with a standard "undo"
|
||||
* action. Plugins may need to handle reverting this property change if
|
||||
* necessary.
|
||||
*/
|
||||
Q_PROPERTY(int pan READ pan WRITE setPan)
|
||||
/**
|
||||
* Channel chorus, from 0 to 127.
|
||||
* \note Changing this property is **not** revertable with a standard "undo"
|
||||
* action. Plugins may need to handle reverting this property change if
|
||||
* necessary.
|
||||
*/
|
||||
Q_PROPERTY(int chorus READ chorus WRITE setChorus)
|
||||
/**
|
||||
* Channel reverb, from 0 to 127.
|
||||
* \note Changing this property is **not** revertable with a standard "undo"
|
||||
* action. Plugins may need to handle reverting this property change if
|
||||
* necessary.
|
||||
*/
|
||||
Q_PROPERTY(int reverb READ reverb WRITE setReverb)
|
||||
/**
|
||||
* Whether this channel is muted.
|
||||
* \note Changing this property is **not** revertable with a standard "undo"
|
||||
* action. Plugins may need to handle reverting this property change if
|
||||
* necessary.
|
||||
*/
|
||||
Q_PROPERTY(bool mute READ mute WRITE setMute)
|
||||
|
||||
/**
|
||||
* MIDI program number, from 0 to 127. Changing this property is recorded
|
||||
* to the program's undo stack and can be reverted with a standard "undo"
|
||||
* action.
|
||||
*/
|
||||
Q_PROPERTY(int midiProgram READ midiProgram WRITE setMidiProgram)
|
||||
/**
|
||||
* MIDI patch bank number. Changing this property is recorded
|
||||
* to the program's undo stack and can be reverted with a standard "undo"
|
||||
* action.
|
||||
*/
|
||||
Q_PROPERTY(int midiBank READ midiBank WRITE setMidiBank)
|
||||
|
||||
Ms::Channel* activeChannel();
|
||||
|
||||
void setMidiBankAndProgram(int bank, int program, bool setUserBankController);
|
||||
|
||||
public:
|
||||
/// \cond MS_INTERNAL
|
||||
Channel(Ms::Channel* ch, Ms::Part* p, QObject* parent = nullptr)
|
||||
: QObject(parent), _channel(ch), _part(p) {}
|
||||
|
||||
QString name() const { return _channel->name(); }
|
||||
|
||||
int volume() const { return _channel->volume(); }
|
||||
void setVolume(int val) { activeChannel()->setVolume(qBound(0, val, 127)); }
|
||||
int pan() const { return _channel->pan(); }
|
||||
void setPan(int val) { activeChannel()->setPan(qBound(0, val, 127)); }
|
||||
int chorus() const { return _channel->chorus(); }
|
||||
void setChorus(int val) { activeChannel()->setChorus(qBound(0, val, 127)); }
|
||||
int reverb() const { return _channel->reverb(); }
|
||||
void setReverb(int val) { activeChannel()->setReverb(qBound(0, val, 127)); }
|
||||
|
||||
bool mute() const { return _channel->mute(); }
|
||||
void setMute(bool val) { activeChannel()->setMute(val); }
|
||||
|
||||
int midiProgram() const { return _channel->program(); }
|
||||
void setMidiProgram(int prog);
|
||||
int midiBank() const { return _channel->bank(); }
|
||||
void setMidiBank(int bank);
|
||||
/// \endcond
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// StringData
|
||||
/// \since MuseScore 3.5
|
||||
//---------------------------------------------------------
|
||||
|
||||
class StringData : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
/**
|
||||
* List of strings in this instrument.
|
||||
* \returns A list of objects representing strings. Each
|
||||
* object has the following fields:
|
||||
* - \p pitch - pitch of this string on fret 0 (integer).
|
||||
* - \p open - if \p true, this string is not fretted and
|
||||
* always open. If \p false, the string **is**
|
||||
* fretted. For example, for classical guitar
|
||||
* all strings are fretted, and for them
|
||||
* \p open value will always be \p false.
|
||||
*/
|
||||
Q_PROPERTY(QVariantList strings READ stringList)
|
||||
|
||||
/** Number of frets in this instrument */
|
||||
Q_PROPERTY(int frets READ frets)
|
||||
|
||||
Ms::StringData _data;
|
||||
|
||||
public:
|
||||
/// \cond MS_INTERNAL
|
||||
StringData(const Ms::StringData* d, QObject* parent = nullptr)
|
||||
: QObject(parent), _data(*d) {}
|
||||
|
||||
QVariantList stringList() const;
|
||||
int frets() const { return _data.frets(); }
|
||||
/// \endcond
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ChannelListProperty
|
||||
/// \cond PLUGIN_API \private \endcond
|
||||
//---------------------------------------------------------
|
||||
|
||||
class ChannelListProperty : public QQmlListProperty<Channel>
|
||||
{
|
||||
public:
|
||||
ChannelListProperty(Instrument* i);
|
||||
|
||||
static int count(QQmlListProperty<Channel>* l);
|
||||
static Channel* at(QQmlListProperty<Channel>* l, int i);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Instrument
|
||||
/// \since MuseScore 3.5
|
||||
//---------------------------------------------------------
|
||||
|
||||
class Instrument : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
/**
|
||||
* The string identifier
|
||||
* ([MusicXML Sound ID](https://www.musicxml.com/for-developers/standard-sounds/))
|
||||
* for this instrument.
|
||||
* \see \ref Ms::PluginAPI::Part::instrumentId "Part.instrumentId"
|
||||
*/
|
||||
Q_PROPERTY(QString instrumentId READ instrumentId)
|
||||
// Ms::Instrument supports multiple short/long names (for aeolus instruments?)
|
||||
// but in practice only one is actually used. If this gets changed this API could
|
||||
// be expanded.
|
||||
/** The long name for this instrument. */
|
||||
Q_PROPERTY(QString longName READ longName)
|
||||
/** The short name for this instrument. */
|
||||
Q_PROPERTY(QString shortName READ shortName)
|
||||
|
||||
/**
|
||||
* For fretted instruments, an information about this
|
||||
* instrument's strings.
|
||||
*/
|
||||
Q_PROPERTY(Ms::PluginAPI::StringData* stringData READ stringData)
|
||||
|
||||
// TODO: a property for drumset?
|
||||
|
||||
Q_PROPERTY(QQmlListProperty<Ms::PluginAPI::Channel> channels READ channels)
|
||||
|
||||
Ms::Instrument* _instrument;
|
||||
Ms::Part* _part;
|
||||
|
||||
public:
|
||||
/// \cond MS_INTERNAL
|
||||
Instrument(Ms::Instrument* i, Ms::Part* p)
|
||||
: QObject(), _instrument(i), _part(p) {}
|
||||
|
||||
Ms::Instrument* instrument() { return _instrument; }
|
||||
const Ms::Instrument* instrument() const { return _instrument; }
|
||||
|
||||
Ms::Part* part() { return _part; }
|
||||
|
||||
QString instrumentId() const { return instrument()->instrumentId(); }
|
||||
QString longName() const;
|
||||
QString shortName() const;
|
||||
|
||||
StringData* stringData() { return customWrap<StringData>(instrument()->stringData()); }
|
||||
|
||||
ChannelListProperty channels();
|
||||
/// \endcond
|
||||
|
||||
/** Checks whether two variables represent the same object. */
|
||||
Q_INVOKABLE bool is(Ms::PluginAPI::Instrument* other) { return other && instrument() == other->instrument(); }
|
||||
};
|
||||
} // namespace PluginAPI
|
||||
} // namespace Ms
|
||||
|
||||
#endif
|
77
src/plugins/api/part.cpp
Normal file
77
src/plugins/api/part.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
//=============================================================================
|
||||
// MuseScore
|
||||
// Music Composition & Notation
|
||||
//
|
||||
// Copyright (C) 2020 MuseScore BVBA
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2.
|
||||
//
|
||||
// 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, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//=============================================================================
|
||||
|
||||
#include "part.h"
|
||||
#include "instrument.h"
|
||||
|
||||
namespace Ms {
|
||||
namespace PluginAPI {
|
||||
//---------------------------------------------------------
|
||||
// InstrumentListProperty
|
||||
//---------------------------------------------------------
|
||||
|
||||
InstrumentListProperty::InstrumentListProperty(Part* p)
|
||||
: QQmlListProperty<Instrument>(p, p, &count, &at) {}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// InstrumentListProperty::count
|
||||
//---------------------------------------------------------
|
||||
|
||||
int InstrumentListProperty::count(QQmlListProperty<Instrument>* l)
|
||||
{
|
||||
return static_cast<int>(static_cast<Part*>(l->data)->part()->instruments()->size());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// InstrumentListProperty::at
|
||||
//---------------------------------------------------------
|
||||
|
||||
Instrument* InstrumentListProperty::at(QQmlListProperty<Instrument>* l, int i)
|
||||
{
|
||||
Part* part = static_cast<Part*>(l->data);
|
||||
const Ms::InstrumentList* il = part->part()->instruments();
|
||||
|
||||
if (i < 0 || i >= int(il->size())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ms::Instrument* instr = std::next(il->begin(), i)->second;
|
||||
|
||||
return customWrap<Instrument>(instr, part->part());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Part::instruments
|
||||
//---------------------------------------------------------
|
||||
|
||||
InstrumentListProperty Part::instruments()
|
||||
{
|
||||
return InstrumentListProperty(this);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Part::instrumentAtTick
|
||||
//---------------------------------------------------------
|
||||
|
||||
Instrument* Part::instrumentAtTick(int tick)
|
||||
{
|
||||
return customWrap<Instrument>(part()->instrument(Ms::Fraction::fromTicks(tick)), part());
|
||||
}
|
||||
} // namespace PluginAPI
|
||||
} // namespace Ms
|
|
@ -18,6 +18,23 @@
|
|||
|
||||
namespace Ms {
|
||||
namespace PluginAPI {
|
||||
class Instrument;
|
||||
class Part;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// InstrumentListProperty
|
||||
/// \cond PLUGIN_API \private \endcond
|
||||
//---------------------------------------------------------
|
||||
|
||||
class InstrumentListProperty : public QQmlListProperty<Instrument>
|
||||
{
|
||||
public:
|
||||
InstrumentListProperty(Part* p);
|
||||
|
||||
static int count(QQmlListProperty<Instrument>* l);
|
||||
static Instrument* at(QQmlListProperty<Instrument>* l, int i);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Part
|
||||
//---------------------------------------------------------
|
||||
|
@ -68,6 +85,12 @@ class Part : public Ms::PluginAPI::ScoreElement
|
|||
/// \since MuseScore 3.2.1
|
||||
Q_PROPERTY(bool show READ show)
|
||||
|
||||
/**
|
||||
* List of instruments in this part.
|
||||
* \since MuseScore 3.5
|
||||
*/
|
||||
Q_PROPERTY(QQmlListProperty<Ms::PluginAPI::Instrument> instruments READ instruments);
|
||||
|
||||
public:
|
||||
/// \cond MS_INTERNAL
|
||||
Part(Ms::Part* p = nullptr, Ownership o = Ownership::SCORE)
|
||||
|
@ -90,7 +113,15 @@ public:
|
|||
QString shortName() const { return part()->shortName(); }
|
||||
QString partName() const { return part()->partName(); }
|
||||
bool show() const { return part()->show(); }
|
||||
|
||||
InstrumentListProperty instruments();
|
||||
/// \endcond
|
||||
|
||||
/**
|
||||
* Finds an instrument that is active in this part at the given \p tick.
|
||||
* \since MuseScore 3.5
|
||||
*/
|
||||
Q_INVOKABLE Ms::PluginAPI::Instrument* instrumentAtTick(int tick);
|
||||
};
|
||||
} // namespace PluginAPI
|
||||
} // namespace Ms
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "cursor.h"
|
||||
#include "elements.h"
|
||||
#include "fraction.h"
|
||||
#include "instrument.h"
|
||||
#include "score.h"
|
||||
#include "part.h"
|
||||
#include "util.h"
|
||||
|
@ -352,6 +353,9 @@ void PluginAPI::registerQmlTypes()
|
|||
qmlRegisterAnonymousType<Segment>("MuseScore", 3);
|
||||
qmlRegisterAnonymousType<Measure>("MuseScore", 3);
|
||||
qmlRegisterAnonymousType<Part>("MuseScore", 3);
|
||||
qmlRegisterAnonymousType<Instrument>("MuseScore", 3);
|
||||
qmlRegisterAnonymousType<Channel>("MuseScore", 3);
|
||||
qmlRegisterAnonymousType<StringData>("MuseScore", 3);
|
||||
qmlRegisterAnonymousType<Excerpt>("MuseScore", 3);
|
||||
qmlRegisterAnonymousType<Selection>("MuseScore", 3);
|
||||
qmlRegisterAnonymousType<Tie>("MuseScore", 3);
|
||||
|
|
|
@ -107,6 +107,24 @@ Wrapper* wrap(T* t, Ownership own = Ownership::SCORE)
|
|||
|
||||
extern ScoreElement* wrap(Ms::ScoreElement* se, Ownership own = Ownership::SCORE);
|
||||
|
||||
//---------------------------------------------------------
|
||||
// customWrap
|
||||
/// \cond PLUGIN_API \private \endcond
|
||||
/// \internal
|
||||
/// Can be used to construct wrappers which do not
|
||||
/// support standard ownership logic or require
|
||||
/// additional arguments for initialization.
|
||||
//---------------------------------------------------------
|
||||
|
||||
template<class Wrapper, class T, typename ... Args>
|
||||
Wrapper* customWrap(T* t, Args... args)
|
||||
{
|
||||
Wrapper* w = t ? new Wrapper(t, std::forward<Args>(args)...) : nullptr;
|
||||
// All wrapper objects should belong to JavaScript code.
|
||||
QQmlEngine::setObjectOwnership(w, QQmlEngine::JavaScriptOwnership);
|
||||
return w;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
/// QML access to containers.
|
||||
/// A wrapper which provides read-only access for various
|
||||
|
|
Loading…
Reference in a new issue