Implemented note input cursor
This commit is contained in:
parent
854faa2c65
commit
4ffa1a6772
14 changed files with 264 additions and 12 deletions
|
@ -185,7 +185,7 @@ Ret FluidSynth::removeSoundFonts()
|
|||
|
||||
Ret FluidSynth::setupChannels(const std::vector<Event>& events)
|
||||
{
|
||||
IF_ASSERT_FAILED(m_fluid->synth) {
|
||||
if (!m_fluid->synth) {
|
||||
return make_ret(Err::SynthNotInited);
|
||||
}
|
||||
|
||||
|
@ -271,7 +271,7 @@ void FluidSynth::allSoundsOff()
|
|||
|
||||
void FluidSynth::flushSound()
|
||||
{
|
||||
IF_ASSERT_FAILED(m_fluid->synth) {
|
||||
if (!m_fluid->synth) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "xml.h"
|
||||
#include "undo.h"
|
||||
#include "harmony.h"
|
||||
#include "hook.h"
|
||||
|
||||
namespace Ms {
|
||||
//---------------------------------------------------------
|
||||
|
@ -1217,6 +1218,35 @@ void Segment::scanElements(void* data, void (* func)(void*, Element*), bool all)
|
|||
}
|
||||
}
|
||||
|
||||
QRectF Segment::contentRect() const
|
||||
{
|
||||
QRectF result;
|
||||
for (const Element* element: elist()) {
|
||||
if (!element) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (element->isChord()) {
|
||||
const Chord* chord = dynamic_cast<const Chord*>(element);
|
||||
for (const Note* note: chord->notes()) {
|
||||
result = result.united(note->bbox());
|
||||
}
|
||||
|
||||
Hook* hook = chord->hook();
|
||||
if (hook) {
|
||||
QRectF rect = QRectF(hook->pos().x(), hook->pos().y(), hook->width(), hook->height());
|
||||
result = result.united(rect);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
result = result.united(element->bbox());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// firstElement
|
||||
// This function returns the first main element from a
|
||||
|
|
|
@ -136,6 +136,8 @@ public:
|
|||
qreal x() const override { return ipos().x(); }
|
||||
void setX(qreal v) { rxpos() = v; }
|
||||
|
||||
QRectF contentRect() const;
|
||||
|
||||
void insertStaff(int staff);
|
||||
void removeStaff(int staff);
|
||||
|
||||
|
|
|
@ -128,8 +128,10 @@ set(MODULE_SRC
|
|||
${CMAKE_CURRENT_LIST_DIR}/view/viewmodecontrolmodel.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/notationaccessibilitymodel.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/notationaccessibilitymodel.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/playbackcursor.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/playbackcursor.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/playbackcursor.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/noteinputcursor.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/noteinputcursor.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/notationswitchlistmodel.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/notationswitchlistmodel.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/partlistmodel.cpp
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
|
||||
virtual QColor anchorLineColor() const = 0;
|
||||
virtual QColor playbackCursorColor() const = 0;
|
||||
virtual QColor selectionColor() const = 0;
|
||||
virtual QColor selectionColor(int voice = 0) const = 0;
|
||||
|
||||
virtual int selectionProximity() const = 0;
|
||||
|
||||
|
|
|
@ -48,6 +48,9 @@ public:
|
|||
|
||||
virtual void setCurrentVoiceIndex(int voiceIndex) = 0;
|
||||
|
||||
virtual QRectF cursorRect() const = 0;
|
||||
virtual QColor cursorColor() const = 0;
|
||||
|
||||
virtual async::Notification noteAdded() const = 0;
|
||||
virtual async::Notification stateChanged() const = 0;
|
||||
};
|
||||
|
|
|
@ -18,14 +18,15 @@
|
|||
//=============================================================================
|
||||
#include "notationconfiguration.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "io/path.h"
|
||||
|
||||
#include "libmscore/preferences.h"
|
||||
#include "libmscore/mscore.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "settings.h"
|
||||
#include "io/path.h"
|
||||
|
||||
#include "notationtypes.h"
|
||||
|
||||
using namespace mu;
|
||||
using namespace mu::notation;
|
||||
using namespace mu::framework;
|
||||
|
@ -160,9 +161,13 @@ QColor NotationConfiguration::playbackCursorColor() const
|
|||
return c;
|
||||
}
|
||||
|
||||
QColor NotationConfiguration::selectionColor() const
|
||||
QColor NotationConfiguration::selectionColor(int voice) const
|
||||
{
|
||||
return Ms::MScore::selectColor[0];
|
||||
if (!isVoiceIndexValid(voice)) {
|
||||
return QColor();
|
||||
}
|
||||
|
||||
return Ms::MScore::selectColor[voice];
|
||||
}
|
||||
|
||||
int NotationConfiguration::selectionProximity() const
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
io::path foregroundWallpaper() const override;
|
||||
|
||||
QColor playbackCursorColor() const override;
|
||||
QColor selectionColor() const override;
|
||||
QColor selectionColor(int voice) const override;
|
||||
|
||||
int selectionProximity() const override;
|
||||
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#include "libmscore/chord.h"
|
||||
#include "libmscore/slur.h"
|
||||
#include "libmscore/articulation.h"
|
||||
#include "libmscore/system.h"
|
||||
#include "libmscore/page.h"
|
||||
#include "libmscore/stafftype.h"
|
||||
|
||||
#include "scorecallbacks.h"
|
||||
|
||||
|
@ -255,6 +258,63 @@ void NotationNoteInput::putTuplet(const TupletOptions& options)
|
|||
m_stateChanged.notify();
|
||||
}
|
||||
|
||||
QRectF NotationNoteInput::cursorRect() const
|
||||
{
|
||||
if (!isNoteInputMode()) {
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
Ms::InputState& inputState = score()->inputState();
|
||||
Ms::Segment* segment = inputState.segment();
|
||||
if (!segment) {
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
Ms::System* system = segment->measure()->system();
|
||||
if (!system) {
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
int track = inputState.track() == -1 ? 0 : inputState.track();
|
||||
int staffIdx = track / VOICES;
|
||||
|
||||
QRectF segmentContentRect = segment->contentRect();
|
||||
double x = segmentContentRect.translated(segment->pagePos()).x() - 6;
|
||||
double y = system->staffYpage(staffIdx) + system->page()->pos().y();
|
||||
double w = segmentContentRect.width() + 12;
|
||||
|
||||
double h;
|
||||
|
||||
Staff* staff = score()->staff(staffIdx);
|
||||
const Ms::StaffType* staffType = staff->staffType(inputState.tick());
|
||||
double spatium = score()->spatium();
|
||||
double lineDist = staffType->lineDistance().val() * spatium;
|
||||
int lines = staffType->lines();
|
||||
int strg = inputState.string();
|
||||
|
||||
int instrStrgs = staff->part()->instrument()->stringData()->strings();
|
||||
if (staff->isTabStaff(inputState.tick()) && strg >= 0 && strg <= instrStrgs) {
|
||||
h = lineDist;
|
||||
y += staffType->physStringToYOffset(strg) * spatium;
|
||||
y -= (staffType->onLines() ? lineDist * 0.5 : lineDist);
|
||||
} else {
|
||||
h = (lines - 1) * lineDist + 4 * spatium;
|
||||
y -= 2.0 * spatium;
|
||||
}
|
||||
|
||||
QRectF result = QRectF(x, y, w, h);
|
||||
return result;
|
||||
}
|
||||
|
||||
QColor NotationNoteInput::cursorColor() const
|
||||
{
|
||||
Ms::InputState& inputState = score()->inputState();
|
||||
int track = inputState.track() == -1 ? 0 : inputState.track();
|
||||
int voice = track % VOICES;
|
||||
|
||||
return configuration()->selectionColor(voice);
|
||||
}
|
||||
|
||||
void NotationNoteInput::setSlur(Ms::Slur* slur)
|
||||
{
|
||||
Ms::InputState& inputState = score()->inputState();
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
#define MU_NOTATION_NOTATIONNOTEINPUT_H
|
||||
|
||||
#include "../inotationnoteinput.h"
|
||||
#include "modularity/ioc.h"
|
||||
#include "async/asyncable.h"
|
||||
#include "inotationconfiguration.h"
|
||||
#include "igetscore.h"
|
||||
#include "inotationinteraction.h"
|
||||
#include "inotationundostack.h"
|
||||
|
@ -33,6 +35,8 @@ namespace mu::notation {
|
|||
class ScoreCallbacks;
|
||||
class NotationNoteInput : public INotationNoteInput, public async::Asyncable
|
||||
{
|
||||
INJECT(notation, INotationConfiguration, configuration)
|
||||
|
||||
public:
|
||||
NotationNoteInput(const IGetScore* getScore, INotationInteraction* interaction, INotationUndoStackPtr undoStack);
|
||||
~NotationNoteInput() override;
|
||||
|
@ -56,6 +60,9 @@ public:
|
|||
|
||||
void setCurrentVoiceIndex(int voiceIndex) override;
|
||||
|
||||
QRectF cursorRect() const override;
|
||||
QColor cursorColor() const override;
|
||||
|
||||
async::Notification noteAdded() const override;
|
||||
async::Notification stateChanged() const override;
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ NotationPaintView::NotationPaintView(QQuickItem* parent)
|
|||
m_playbackCursor->setColor(configuration()->playbackCursorColor());
|
||||
m_playbackCursor->setVisible(false);
|
||||
|
||||
m_noteInputCursor = new NoteInputCursor();
|
||||
|
||||
playbackController()->isPlayingChanged().onNotify(this, [this]() {
|
||||
onPlayingChanged();
|
||||
});
|
||||
|
@ -73,6 +75,7 @@ NotationPaintView::~NotationPaintView()
|
|||
{
|
||||
delete m_inputController;
|
||||
delete m_playbackCursor;
|
||||
delete m_noteInputCursor;
|
||||
}
|
||||
|
||||
void NotationPaintView::handleAction(const QString& actionName)
|
||||
|
@ -208,6 +211,7 @@ void NotationPaintView::paint(QPainter* painter)
|
|||
m_notation->paint(painter, toLogical(rect));
|
||||
|
||||
m_playbackCursor->paint(painter);
|
||||
m_noteInputCursor->paint(painter);
|
||||
} else {
|
||||
painter->drawText(10, 10, "no notation");
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include "notationviewinputcontroller.h"
|
||||
#include "playbackcursor.h"
|
||||
#include "noteinputcursor.h"
|
||||
|
||||
namespace mu {
|
||||
namespace notation {
|
||||
|
@ -124,6 +125,7 @@ private:
|
|||
QTransform m_matrix;
|
||||
NotationViewInputController* m_inputController = nullptr;
|
||||
PlaybackCursor* m_playbackCursor = nullptr;
|
||||
NoteInputCursor* m_noteInputCursor = nullptr;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
84
src/notation/view/noteinputcursor.cpp
Normal file
84
src/notation/view/noteinputcursor.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
//=============================================================================
|
||||
// MuseScore
|
||||
// Music Composition & Notation
|
||||
//
|
||||
// Copyright (C) 2020 MuseScore BVBA and others
|
||||
//
|
||||
// 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 "noteinputcursor.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
using namespace mu::notation;
|
||||
|
||||
void NoteInputCursor::paint(QPainter* painter)
|
||||
{
|
||||
if (!isNoteInputMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QRectF cursorRect = rect();
|
||||
QColor fillColor = color();
|
||||
fillColor.setAlpha(50);
|
||||
painter->fillRect(cursorRect, fillColor);
|
||||
|
||||
QRectF leftLine = QRectF(cursorRect.topLeft().x(), cursorRect.topLeft().y(), 3, cursorRect.height());
|
||||
QColor lineColor = color();
|
||||
painter->fillRect(leftLine, lineColor);
|
||||
}
|
||||
|
||||
INotationNoteInputPtr NoteInputCursor::currentNoteInput() const
|
||||
{
|
||||
auto notation = globalContext()->currentNotation();
|
||||
if (!notation) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto interaction = notation->interaction();
|
||||
if (!interaction) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return interaction->noteInput();
|
||||
}
|
||||
|
||||
bool NoteInputCursor::isNoteInputMode() const
|
||||
{
|
||||
auto noteInput = currentNoteInput();
|
||||
if (!noteInput) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return noteInput->isNoteInputMode();
|
||||
}
|
||||
|
||||
QRectF NoteInputCursor::rect() const
|
||||
{
|
||||
auto noteInput = currentNoteInput();
|
||||
if (!noteInput) {
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
return noteInput->cursorRect();
|
||||
}
|
||||
|
||||
QColor NoteInputCursor::color() const
|
||||
{
|
||||
auto noteInput = currentNoteInput();
|
||||
if (!noteInput) {
|
||||
return QColor();
|
||||
}
|
||||
|
||||
return noteInput->cursorColor();
|
||||
}
|
53
src/notation/view/noteinputcursor.h
Normal file
53
src/notation/view/noteinputcursor.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
//=============================================================================
|
||||
// MuseScore
|
||||
// Music Composition & Notation
|
||||
//
|
||||
// Copyright (C) 2020 MuseScore BVBA and others
|
||||
//
|
||||
// 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 MU_NOTATION_NOTEINPUTCURSOR_H
|
||||
#define MU_NOTATION_NOTEINPUTCURSOR_H
|
||||
|
||||
#include <QRect>
|
||||
#include <QColor>
|
||||
|
||||
#include "modularity/ioc.h"
|
||||
#include "context/iglobalcontext.h"
|
||||
#include "async/asyncable.h"
|
||||
#include "inotationconfiguration.h"
|
||||
|
||||
class QPainter;
|
||||
|
||||
namespace mu::notation {
|
||||
class NoteInputCursor : public async::Asyncable
|
||||
{
|
||||
INJECT(notation, context::IGlobalContext, globalContext)
|
||||
INJECT(notation, INotationConfiguration, configuration)
|
||||
|
||||
public:
|
||||
|
||||
NoteInputCursor() = default;
|
||||
|
||||
void paint(QPainter* painter);
|
||||
|
||||
private:
|
||||
INotationNoteInputPtr currentNoteInput() const;
|
||||
|
||||
bool isNoteInputMode() const;
|
||||
QRectF rect() const;
|
||||
QColor color() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MU_NOTATION_NOTEINPUTCURSOR_H
|
Loading…
Reference in a new issue