Implemented insert/append measures
This commit is contained in:
parent
f7bfa2decd
commit
985be90184
11 changed files with 270 additions and 4 deletions
|
@ -60,7 +60,7 @@ public:
|
|||
virtual async::Notification selectionChanged() const = 0;
|
||||
|
||||
// Drag
|
||||
using IsDraggable = std::function<bool(const Element*)>;
|
||||
using IsDraggable = std::function<bool (const Element*)>;
|
||||
virtual bool isDragStarted() const = 0;
|
||||
virtual void startDrag(const std::vector<Element*>& elems, const QPointF& eoffset, const IsDraggable& isDrag) = 0;
|
||||
virtual void drag(const QPointF& fromPos, const QPointF& toPos, DragMode mode) = 0;
|
||||
|
@ -94,6 +94,8 @@ public:
|
|||
// Measure
|
||||
virtual void splitSelectedMeasure() = 0;
|
||||
virtual void joinSelectedMeasures() = 0;
|
||||
virtual void insertMeasures(int afterMeasureIndex, int count) = 0;
|
||||
virtual void appendMeasures(int count) = 0;
|
||||
|
||||
virtual void copySelection() = 0;
|
||||
virtual void pasteSelection(const Fraction& scale = Fraction(1, 1)) = 0;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <QPoint>
|
||||
|
||||
#include "log.h"
|
||||
#include "notationtypes.h"
|
||||
|
||||
using namespace mu::notation;
|
||||
using namespace mu::actions;
|
||||
|
@ -78,6 +79,10 @@ void NotationActionController::init()
|
|||
|
||||
dispatcher()->reg(this, "split-measure", this, &NotationActionController::splitMeasure);
|
||||
dispatcher()->reg(this, "join-measures", this, &NotationActionController::joinSelectedMeasures);
|
||||
dispatcher()->reg(this, "insert-measure", this, &NotationActionController::insertMeasure);
|
||||
dispatcher()->reg(this, "insert-measures", this, &NotationActionController::insertMeasures);
|
||||
dispatcher()->reg(this, "append-measure", this, &NotationActionController::appendMeasure);
|
||||
dispatcher()->reg(this, "append-measures", this, &NotationActionController::appendMeasures);
|
||||
|
||||
dispatcher()->reg(this, "edit-style", this, &NotationActionController::openPageStyle);
|
||||
dispatcher()->reg(this, "staff-properties", this, &NotationActionController::openStaffProperties);
|
||||
|
@ -375,6 +380,68 @@ void NotationActionController::joinSelectedMeasures()
|
|||
interaction->joinSelectedMeasures();
|
||||
}
|
||||
|
||||
void NotationActionController::insertMeasure()
|
||||
{
|
||||
auto interaction = currentNotationInteraction();
|
||||
if (!interaction) {
|
||||
return;
|
||||
}
|
||||
|
||||
int lastSelectedMeasureIndex = this->lastSelectedMeasureIndex();
|
||||
|
||||
if (lastSelectedMeasureIndex == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
interaction->insertMeasures(lastSelectedMeasureIndex, 1);
|
||||
}
|
||||
|
||||
void NotationActionController::insertMeasures()
|
||||
{
|
||||
auto interaction = currentNotationInteraction();
|
||||
if (!interaction) {
|
||||
return;
|
||||
}
|
||||
|
||||
int lastSelectedMeasureIndex = this->lastSelectedMeasureIndex();
|
||||
|
||||
if (lastSelectedMeasureIndex == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
RetVal<Val> measureCount = interactive()->open("musescore://notation/selectmeasurescount?operation=insert");
|
||||
if (!measureCount.ret) {
|
||||
return;
|
||||
}
|
||||
|
||||
interaction->insertMeasures(lastSelectedMeasureIndex, measureCount.val.toInt());
|
||||
}
|
||||
|
||||
void NotationActionController::appendMeasure()
|
||||
{
|
||||
auto interaction = currentNotationInteraction();
|
||||
if (!interaction) {
|
||||
return;
|
||||
}
|
||||
|
||||
interaction->appendMeasures(1);
|
||||
}
|
||||
|
||||
void NotationActionController::appendMeasures()
|
||||
{
|
||||
auto interaction = currentNotationInteraction();
|
||||
if (!interaction) {
|
||||
return;
|
||||
}
|
||||
|
||||
RetVal<Val> measureCount = interactive()->open("musescore://notation/selectcountmeasures?operation=append");
|
||||
if (!measureCount.ret) {
|
||||
return;
|
||||
}
|
||||
|
||||
interaction->appendMeasures(measureCount.val.toInt());
|
||||
}
|
||||
|
||||
void NotationActionController::openPageStyle()
|
||||
{
|
||||
interactive()->open("musescore://notation/style");
|
||||
|
@ -410,3 +477,21 @@ void NotationActionController::openPartsDialog()
|
|||
{
|
||||
interactive()->open("musescore://notation/parts");
|
||||
}
|
||||
|
||||
int NotationActionController::lastSelectedMeasureIndex() const
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
auto interaction = currentNotationInteraction();
|
||||
if (!interaction) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (interaction->selection()->isRange()) {
|
||||
result = interaction->selection()->range()->endMeasureIndex();
|
||||
} else {
|
||||
result = interaction->selection()->element()->findMeasure()->index();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -60,9 +60,12 @@ private:
|
|||
void redo();
|
||||
void selectAll();
|
||||
|
||||
|
||||
void splitMeasure();
|
||||
void joinSelectedMeasures();
|
||||
void insertMeasure();
|
||||
void insertMeasures();
|
||||
void appendMeasure();
|
||||
void appendMeasures();
|
||||
|
||||
void openPageStyle();
|
||||
void openStaffProperties();
|
||||
|
@ -80,6 +83,8 @@ private:
|
|||
|
||||
void pasteSelection(PastingType type = PastingType::Default);
|
||||
Fraction resolvePastingScale(const INotationInteractionPtr& interaction, PastingType type) const;
|
||||
|
||||
int lastSelectedMeasureIndex() const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -219,6 +219,22 @@ const ActionList NotationActions::m_actions = {
|
|||
Action("join-measures",
|
||||
QT_TRANSLATE_NOOP("action", "Join Selected Measures"),
|
||||
ShortcutContext::NotationActive
|
||||
),
|
||||
Action("insert-measure",
|
||||
QT_TRANSLATE_NOOP("action", "Insert Measure"),
|
||||
ShortcutContext::NotationActive
|
||||
),
|
||||
Action("insert-measures",
|
||||
QT_TRANSLATE_NOOP("action", "Insert Measures"),
|
||||
ShortcutContext::NotationActive
|
||||
),
|
||||
Action("append-measure",
|
||||
QT_TRANSLATE_NOOP("action", "Append Measure"),
|
||||
ShortcutContext::NotationActive
|
||||
),
|
||||
Action("append-measures",
|
||||
QT_TRANSLATE_NOOP("action", "Append Measures"),
|
||||
ShortcutContext::NotationActive
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
@ -1978,6 +1978,46 @@ void NotationInteraction::joinSelectedMeasures()
|
|||
m_selectionChanged.notify();
|
||||
}
|
||||
|
||||
void NotationInteraction::insertMeasures(int afterMeasureIndex, int count)
|
||||
{
|
||||
Measure* measure = score()->crMeasure(afterMeasureIndex);
|
||||
|
||||
if (!measure) {
|
||||
return;
|
||||
}
|
||||
|
||||
score()->startCmd();
|
||||
for (int i = 0; i < count; i++) {
|
||||
score()->insertMeasure(ElementType::MEASURE, measure);
|
||||
}
|
||||
score()->endCmd();
|
||||
|
||||
clearSelection();
|
||||
|
||||
for (int i = afterMeasureIndex + 1; i <= afterMeasureIndex + count; i++) {
|
||||
Measure* measure = score()->crMeasure(i - 1);
|
||||
select(measure, SelectType::RANGE);
|
||||
}
|
||||
}
|
||||
|
||||
void NotationInteraction::appendMeasures(int count)
|
||||
{
|
||||
int measureCount = score()->measures()->size();
|
||||
|
||||
score()->startCmd();
|
||||
for (int i = 0; i < count; i++) {
|
||||
score()->insertMeasure(ElementType::MEASURE, nullptr);
|
||||
}
|
||||
score()->endCmd();
|
||||
|
||||
clearSelection();
|
||||
|
||||
for (int i = measureCount; i < measureCount + count; i++) {
|
||||
Measure* measure = score()->crMeasure(i - 1);
|
||||
select(measure, SelectType::RANGE);
|
||||
}
|
||||
}
|
||||
|
||||
void NotationInteraction::copySelection()
|
||||
{
|
||||
if (!selection()->canCopy()) {
|
||||
|
|
|
@ -111,6 +111,8 @@ public:
|
|||
// Measure
|
||||
void splitSelectedMeasure() override;
|
||||
void joinSelectedMeasures() override;
|
||||
void insertMeasures(int afterMeasureIndex, int count) override;
|
||||
void appendMeasures(int count) override;
|
||||
|
||||
void copySelection() override;
|
||||
void pasteSelection(const Fraction& scale = Fraction(1, 1)) override;
|
||||
|
|
|
@ -272,8 +272,8 @@ int NotationSelectionRange::sectionElementsMinY(const NotationSelectionRange::Ra
|
|||
NotationSelectionRange::MeasureRange NotationSelectionRange::measureRange() const
|
||||
{
|
||||
const Ms::Selection& selection = score()->selection();
|
||||
Measure* startMeasure;
|
||||
Measure* endMeasure;
|
||||
Measure* startMeasure = nullptr;
|
||||
Measure* endMeasure = nullptr;
|
||||
selection.measureRange(&startMeasure, &endMeasure);
|
||||
|
||||
MeasureRange range;
|
||||
|
|
|
@ -123,6 +123,9 @@ void NotationModule::resolveImports()
|
|||
|
||||
ir->registerUri(Uri("musescore://notation/noteinputbar/customise"),
|
||||
ContainerMeta(ContainerType::QmlDialog, "MuseScore/NotationScene/NoteInputBarCustomiseDialog.qml"));
|
||||
|
||||
ir->registerUri(Uri("musescore://notation/selectmeasurescount"),
|
||||
ContainerMeta(ContainerType::QmlDialog, "MuseScore/NotationScene/SelectMeasuresCountDialog.qml"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,5 +21,6 @@
|
|||
<file>qml/MuseScore/NotationScene/NoteInputBarCustomiseDialog.qml</file>
|
||||
<file>qml/MuseScore/NotationScene/internal/NoteInputBarActionDelegate.qml</file>
|
||||
<file>qml/MuseScore/NotationScene/internal/NoteInputBarSeparatorDelegate.qml</file>
|
||||
<file>qml/MuseScore/NotationScene/SelectMeasuresCountDialog.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "libmscore/staff.h"
|
||||
#include "libmscore/stafftype.h"
|
||||
#include "libmscore/score.h"
|
||||
#include "libmscore/measure.h"
|
||||
|
||||
#include "instruments/instrumentstypes.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
|
||||
import MuseScore.Ui 1.0
|
||||
import MuseScore.UiComponents 1.0
|
||||
|
||||
QmlDialog {
|
||||
id: root
|
||||
|
||||
width: 534
|
||||
height: 146
|
||||
|
||||
modal: true
|
||||
|
||||
property string operation: ""
|
||||
|
||||
Rectangle {
|
||||
id: content
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
color: ui.theme.popupBackgroundColor
|
||||
|
||||
property int measuresCount: 1
|
||||
|
||||
QtObject {
|
||||
id: privateProperties
|
||||
|
||||
readonly property int sideMargin: 16
|
||||
|
||||
function capitalizeFirstLetter(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: privateProperties.sideMargin
|
||||
|
||||
spacing: 20
|
||||
|
||||
Column {
|
||||
Layout.fillWidth: true
|
||||
|
||||
spacing: 12
|
||||
|
||||
StyledTextLabel {
|
||||
text: privateProperties.capitalizeFirstLetter(operation) + " " + qsTrc("notation", "empty measures")
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
spacing: 12
|
||||
|
||||
StyledTextLabel {
|
||||
Layout.fillWidth: true
|
||||
text: qsTrc("notation", "Number of measures to ") + operation.toLowerCase() + ":"
|
||||
}
|
||||
|
||||
IncrementalPropertyControl {
|
||||
id: countMeasuresInputField
|
||||
|
||||
Layout.alignment: Qt.AlignRight
|
||||
Layout.preferredWidth: 100
|
||||
|
||||
iconMode: iconModeEnum.hidden
|
||||
currentValue: content.measuresCount
|
||||
step: 1
|
||||
|
||||
maxValue: 1000
|
||||
minValue: 1
|
||||
validator: IntInputValidator {
|
||||
top: countMeasuresInputField.maxValue
|
||||
bottom: countMeasuresInputField.minValue
|
||||
}
|
||||
|
||||
onValueEdited: {
|
||||
content.measuresCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
Layout.preferredHeight: childrenRect.height
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignBottom
|
||||
|
||||
spacing: 12
|
||||
|
||||
FlatButton {
|
||||
text: qsTrc("global", "Cancel")
|
||||
|
||||
onClicked: {
|
||||
root.reject()
|
||||
}
|
||||
}
|
||||
|
||||
FlatButton {
|
||||
text: qsTrc("global", "Ok")
|
||||
|
||||
onClicked: {
|
||||
root.ret = {errcode: 0, value: content.measuresCount}
|
||||
root.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue