implemented half/double/special pasting

This commit is contained in:
Roman Pudashkin 2020-11-06 17:26:06 +02:00 committed by pereverzev+v
parent bb47db35e6
commit eb75e378eb
10 changed files with 67 additions and 27 deletions

View file

@ -19,22 +19,19 @@
#ifndef MU_NOTATION_INOTATIONINPUTSTATE_H #ifndef MU_NOTATION_INOTATIONINPUTSTATE_H
#define MU_NOTATION_INOTATIONINPUTSTATE_H #define MU_NOTATION_INOTATIONINPUTSTATE_H
#include "async/notification.h"
#include "notationtypes.h" #include "notationtypes.h"
namespace mu { namespace mu::notation {
namespace notation {
class INotationInputState class INotationInputState
{ {
public: public:
virtual ~INotationInputState() = default; virtual ~INotationInputState() = default;
virtual bool isNoteEnterMode() const = 0; virtual bool isNoteEnterMode() const = 0;
virtual DurationType duration() const = 0; virtual Duration duration() const = 0;
}; };
using INotationInputStatePtr = std::shared_ptr<INotationInputState>; using INotationInputStatePtr = std::shared_ptr<INotationInputState>;
} }
}
#endif // MU_NOTATION_INOTATIONINPUTSTATE_H #endif // MU_NOTATION_INOTATIONINPUTSTATE_H

View file

@ -92,7 +92,7 @@ public:
virtual async::Notification textEditingChanged() const = 0; virtual async::Notification textEditingChanged() const = 0;
virtual void copySelection() = 0; virtual void copySelection() = 0;
virtual void pasteSelection() = 0; virtual void pasteSelection(const Fraction& scale = Fraction(1, 1)) = 0;
virtual void deleteSelection() = 0; virtual void deleteSelection() = 0;
virtual void setBreaksSpawnInterval(BreaksSpawnIntervalType intervalType, int interval = 0) = 0; virtual void setBreaksSpawnInterval(BreaksSpawnIntervalType intervalType, int interval = 0) = 0;

View file

@ -49,7 +49,10 @@ void NotationActionController::init()
dispatcher()->reg(this, "cut", this, &NotationActionController::cutSelection); dispatcher()->reg(this, "cut", this, &NotationActionController::cutSelection);
dispatcher()->reg(this, "copy", this, &NotationActionController::copySelection); dispatcher()->reg(this, "copy", this, &NotationActionController::copySelection);
dispatcher()->reg(this, "paste", this, &NotationActionController::pasteSelection); dispatcher()->reg(this, "paste", [this]() { pasteSelection(PastingType::Default); });
dispatcher()->reg(this, "paste-half", [this]() { pasteSelection(PastingType::Half); });
dispatcher()->reg(this, "paste-double", [this]() { pasteSelection(PastingType::Double); });
dispatcher()->reg(this, "paste-special", [this]() { pasteSelection(PastingType::Special); });
dispatcher()->reg(this, "delete", this, &NotationActionController::deleteSelection); dispatcher()->reg(this, "delete", this, &NotationActionController::deleteSelection);
dispatcher()->reg(this, "undo", this, &NotationActionController::undo); dispatcher()->reg(this, "undo", this, &NotationActionController::undo);
dispatcher()->reg(this, "redo", this, &NotationActionController::redo); dispatcher()->reg(this, "redo", this, &NotationActionController::redo);
@ -75,7 +78,7 @@ bool NotationActionController::canReceiveAction(const actions::ActionName&) cons
return true; return true;
} }
std::shared_ptr<INotation> NotationActionController::currentNotation() const INotationPtr NotationActionController::currentNotation() const
{ {
return globalContext()->currentNotation(); return globalContext()->currentNotation();
} }
@ -247,14 +250,38 @@ void NotationActionController::copySelection()
interaction->copySelection(); interaction->copySelection();
} }
void NotationActionController::pasteSelection() void NotationActionController::pasteSelection(PastingType type)
{ {
auto interaction = currentNotationInteraction(); auto interaction = currentNotationInteraction();
if (!interaction) { if (!interaction) {
return; return;
} }
interaction->pasteSelection(); Fraction scale = resolvePastingScale(interaction, type);
interaction->pasteSelection(scale);
}
Fraction NotationActionController::resolvePastingScale(const INotationInteractionPtr& interaction, PastingType type) const
{
const Fraction DEFAULT_SCALE(1, 1);
switch (type) {
case PastingType::Default: return DEFAULT_SCALE;
case PastingType::Half: return Fraction(1, 2);
case PastingType::Double: return Fraction(2, 1);
case PastingType::Special:
Fraction scale = DEFAULT_SCALE;
Fraction duration = interaction->inputState()->duration().fraction();
if (duration.isValid() && !duration.isZero()) {
scale = duration * 4;
scale.reduce();
}
return scale;
}
return DEFAULT_SCALE;
} }
void NotationActionController::deleteSelection() void NotationActionController::deleteSelection()

View file

@ -53,7 +53,6 @@ private:
void cutSelection(); void cutSelection();
void copySelection(); void copySelection();
void pasteSelection();
void deleteSelection(); void deleteSelection();
void undo(); void undo();
void redo(); void redo();
@ -65,6 +64,16 @@ private:
void openScoreProperties(); void openScoreProperties();
void openTransposeDialog(); void openTransposeDialog();
void openPartsDialog(); void openPartsDialog();
enum class PastingType {
Default,
Half,
Double,
Special
};
void pasteSelection(PastingType type);
Fraction resolvePastingScale(const INotationInteractionPtr& interaction, PastingType type) const;
}; };
} }

View file

@ -124,6 +124,18 @@ const std::vector<Action> NotationActions::m_actions = {
QT_TRANSLATE_NOOP("action", "Paste"), QT_TRANSLATE_NOOP("action", "Paste"),
ShortcutContext::NotationActive ShortcutContext::NotationActive
), ),
Action("paste-half",
QT_TRANSLATE_NOOP("action", "Paste Half Duration"),
ShortcutContext::NotationActive
),
Action("paste-double",
QT_TRANSLATE_NOOP("action", "Paste Double Duration"),
ShortcutContext::NotationActive
),
Action("paste-special",
QT_TRANSLATE_NOOP("action", "Paste Special"),
ShortcutContext::NotationActive
),
Action("swap", Action("swap",
QT_TRANSLATE_NOOP("action", "Swap"), QT_TRANSLATE_NOOP("action", "Swap"),
ShortcutContext::NotationActive ShortcutContext::NotationActive

View file

@ -23,7 +23,7 @@
using namespace mu::notation; using namespace mu::notation;
NotationInputState::NotationInputState(IGetScore* getScore) NotationInputState::NotationInputState(const IGetScore* getScore)
: m_getScore(getScore) : m_getScore(getScore)
{ {
} }
@ -38,7 +38,7 @@ bool NotationInputState::isNoteEnterMode() const
return score()->inputState().noteEntryMode(); return score()->inputState().noteEntryMode();
} }
DurationType NotationInputState::duration() const Duration NotationInputState::duration() const
{ {
return score()->inputState().duration().type(); return score()->inputState().duration();
} }

View file

@ -19,32 +19,26 @@
#ifndef MU_NOTATION_NOTATIONINPUTSTATE_H #ifndef MU_NOTATION_NOTATIONINPUTSTATE_H
#define MU_NOTATION_NOTATIONINPUTSTATE_H #define MU_NOTATION_NOTATIONINPUTSTATE_H
#include <map>
#include "../inotationinputstate.h" #include "../inotationinputstate.h"
#include "igetscore.h" #include "igetscore.h"
namespace Ms { namespace Ms {
class Score; class Score;
} }
namespace mu { namespace mu::notation {
namespace notation {
class NotationInputState : public INotationInputState class NotationInputState : public INotationInputState
{ {
public: public:
NotationInputState(IGetScore* getScore); NotationInputState(const IGetScore* getScore);
bool isNoteEnterMode() const override; bool isNoteEnterMode() const override;
DurationType duration() const override; Duration duration() const override;
private: private:
Ms::Score* score() const; Ms::Score* score() const;
const IGetScore* m_getScore = nullptr;
IGetScore* m_getScore = nullptr;
}; };
} }
}
#endif // MU_NOTATION_NOTATIONINPUTSTATE_H #endif // MU_NOTATION_NOTATIONINPUTSTATE_H

View file

@ -1952,12 +1952,12 @@ void NotationInteraction::copySelection()
QApplication::clipboard()->setMimeData(mimeData); QApplication::clipboard()->setMimeData(mimeData);
} }
void NotationInteraction::pasteSelection() void NotationInteraction::pasteSelection(const Fraction& scale)
{ {
m_undoStack->prepareChanges(); m_undoStack->prepareChanges();
const QMimeData* ms = QApplication::clipboard()->mimeData(); const QMimeData* ms = QApplication::clipboard()->mimeData();
score()->cmdPaste(ms, nullptr, Ms::Fraction(1, 1)); score()->cmdPaste(ms, nullptr, scale);
m_undoStack->commitChanges(); m_undoStack->commitChanges();

View file

@ -109,7 +109,7 @@ public:
async::Notification textEditingChanged() const override; async::Notification textEditingChanged() const override;
void copySelection() override; void copySelection() override;
void pasteSelection() override; void pasteSelection(const Fraction& scale = Fraction(1, 1)) override;
void deleteSelection() override; void deleteSelection() override;
void setBreaksSpawnInterval(BreaksSpawnIntervalType intervalType, int interval = 0) override; void setBreaksSpawnInterval(BreaksSpawnIntervalType intervalType, int interval = 0) override;

View file

@ -42,6 +42,7 @@ using Element = Ms::Element;
using ElementType = Ms::ElementType; using ElementType = Ms::ElementType;
using Measure = Ms::Measure; using Measure = Ms::Measure;
using DurationType = Ms::TDuration::DurationType; using DurationType = Ms::TDuration::DurationType;
using Duration = Ms::TDuration;
using SelectType = Ms::SelectType; using SelectType = Ms::SelectType;
using Pad = Ms::Pad; using Pad = Ms::Pad;
using ViewMode = Ms::LayoutMode; // Accomodate inconsistent convention from v3 using ViewMode = Ms::LayoutMode; // Accomodate inconsistent convention from v3