Merge branch 'new_note_input_method' of https://github.com/mgavioli/MuseScore into noteentry
This commit is contained in:
commit
69c0b17495
2 changed files with 111 additions and 10 deletions
|
@ -81,6 +81,18 @@
|
|||
#include "navigator.h"
|
||||
#include "inspector.h"
|
||||
|
||||
// a useful enum for scale steps (could be moved to libmscore/pitchspelling.h)
|
||||
enum {
|
||||
STEP_NONE = -1,
|
||||
STEP_C,
|
||||
STEP_D,
|
||||
STEP_E,
|
||||
STEP_F,
|
||||
STEP_G,
|
||||
STEP_A,
|
||||
STEP_B
|
||||
};
|
||||
|
||||
static const QEvent::Type CloneDrag = QEvent::Type(QEvent::User + 1);
|
||||
extern TextPalette* textPalette;
|
||||
|
||||
|
@ -4833,9 +4845,10 @@ void ScoreView::cmdAddPitch(int note, bool addFlag)
|
|||
is.setDrumNote(pitch);
|
||||
}
|
||||
else {
|
||||
KeySigEvent key = _score->staff(is.track() / VOICES)->keymap()->key(is.tick());
|
||||
// KeySigEvent key = _score->staff(is.track() / VOICES)->keymap()->key(is.tick());
|
||||
int octave = is.pitch / 12;
|
||||
pitch = pitchKeyAdjust(note, key.accidentalType());
|
||||
// pitch = pitchKeyAdjust(note, key.accidentalType());
|
||||
pitch = pitchKeyAdjust(note, 0); // for now, no accidentals (cmdAddPitch1() will compute them)
|
||||
int delta = is.pitch - (octave*12 + pitch);
|
||||
if (delta > 6)
|
||||
is.pitch = (octave+1)*12 + pitch;
|
||||
|
@ -4849,7 +4862,7 @@ void ScoreView::cmdAddPitch(int note, bool addFlag)
|
|||
is.pitch = 127;
|
||||
pitch = is.pitch;
|
||||
}
|
||||
cmdAddPitch1(pitch, addFlag);
|
||||
cmdAddPitch1(pitch, addFlag, note);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -5060,7 +5073,7 @@ void ScoreView::cmdRepeatSelection()
|
|||
const Selection& selection = _score->selection();
|
||||
if (selection.isSingle() && noteEntryMode()) {
|
||||
const InputState& is = _score->inputState();
|
||||
cmdAddPitch1(is.pitch, false);
|
||||
cmdAddPitch1(is.pitch, false, STEP_NONE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5201,11 +5214,24 @@ static void wrongPosition()
|
|||
|
||||
//---------------------------------------------------------
|
||||
// cmdAddPitch1
|
||||
//
|
||||
// Modified to compute note pitch and tpc according to measure context
|
||||
// in addition to key signature, if step != STEP_NONE
|
||||
// (emun for steps provisionaly added at the beginning of this file)
|
||||
//
|
||||
// Note: if step != STEP_NONE, assumes pitch to be for note with no accidental
|
||||
//
|
||||
// Deals with keyboard input (both for new chord and for adding new note to existing chord);
|
||||
// Does NOT deal with mouse input.
|
||||
//
|
||||
// Added parameter 'step' to hold scale step (C=0, D=1, ...) if actual pitch / tpc have to be computed
|
||||
// or STEP_NONE if pitch has to be taken literaly (no context effect).
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreView::cmdAddPitch1(int pitch, bool addFlag)
|
||||
void ScoreView::cmdAddPitch1(int pitch, bool addFlag, int step)
|
||||
{
|
||||
InputState& is = _score->inputState();
|
||||
Drumset * drumSet = is.drumset();
|
||||
|
||||
if (is.segment() == 0) {
|
||||
wrongPosition();
|
||||
|
@ -5223,21 +5249,96 @@ void ScoreView::cmdAddPitch1(int pitch, bool addFlag)
|
|||
if (is.drumset())
|
||||
is.setDrumNote(pitch);
|
||||
}
|
||||
|
||||
// determine actual pitch and tcp according to note input method and context (if required)
|
||||
//
|
||||
// TODO : most or all of this process could be moved to separate functions
|
||||
//
|
||||
// Note: the code below is ready for a 3-level input method (no accidentals at all,
|
||||
// key accidentals only, key + measure context accidentals) according to the value of
|
||||
// some global value (InputState::noteInputMethod is used as a place holder);
|
||||
// level selection statements are commented out
|
||||
|
||||
int line = (pitch / 12) * 7 + step; // compute 'line' (octave*7 + step)
|
||||
int tpc = pitch2tpc(pitch); // get default tpc (without any accidental)
|
||||
|
||||
if(!drumSet && step != STEP_NONE) {
|
||||
// if(is.noteInputMethod() != NOTEINPUTMETHOD_NONE) {
|
||||
// take into account accidentals in current key signature
|
||||
// current tpc value is for a note without accidentals => in the 13 - 19 range (F - B)
|
||||
KeySigEvent key = _score->staff(is.track() / VOICES)->keymap()->key(is.tick());
|
||||
int keyType = key.accidentalType();
|
||||
// if keyType == 0 (no accidentals), do nothing
|
||||
// if key has flats...
|
||||
if(keyType < 0) { // ...our note will be flattened
|
||||
if(tpc >= 20 + keyType) { // if its tpc is <= tpc of B at most as many steps
|
||||
pitch--; // as there are flats in the key
|
||||
tpc -= 7;
|
||||
}
|
||||
}
|
||||
// if key has sharps...
|
||||
else if(keyType > 0) { // ...our note will be sharpened
|
||||
if(tpc <= 12 + keyType) { // if its tpc is >= tpc of F at most as many steps
|
||||
pitch++; // as there are sharps in the key
|
||||
tpc += 7;
|
||||
}
|
||||
}
|
||||
// if(is.noteInputMethod() != NOTEINPUTMMETHOD_KEYSIGONLY) {
|
||||
// take into account accidentals in previous notes on same line (same measure)
|
||||
Chord * chord;
|
||||
Element * elem;
|
||||
// from 1st chord/rest segment of current measure
|
||||
Measure * m = is.segment()->measure();
|
||||
Segment * segm = m->firstCRSegment();
|
||||
int fromTrack = (is.track() / VOICES) * VOICES;
|
||||
int toTrack = fromTrack + VOICES;
|
||||
// scan ChordRest segments up to current input tick
|
||||
while(segm->tick() < is.tick()) {
|
||||
// look in each track of the current input staff
|
||||
for(int i = fromTrack; i < toTrack; i++) {
|
||||
// if element exists and is a chord, check all its notes
|
||||
if( (elem=segm->element(i)) != 0 && elem->type() == CHORD) {
|
||||
chord = static_cast<Chord*>(elem);
|
||||
foreach(Note * note, chord->notes()) {
|
||||
// if chord note is in the same line as input note...
|
||||
if( tpc2step(note->tpc()) + (note->pitch() / 12) * 7 == line) {
|
||||
// ...use its pitch and tpc
|
||||
pitch = note->pitch();
|
||||
tpc = note->tpc();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
segm = segm->next(SegGrace | SegChordRest);
|
||||
}
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
if (noteEntryMode()) {
|
||||
Note* note = _score->addPitch(pitch, addFlag);
|
||||
if (note) {
|
||||
// if Score::addPitch() thought of a different tpc, force note tpc to our value
|
||||
if(!drumSet && step != STEP_NONE && tpc != note->tpc()) {
|
||||
// passing the same line as the note currently has will force it
|
||||
// to be recomputed, if pitch and/or tpc are different
|
||||
_score->undoChangePitch(note, pitch, tpc, note->line());
|
||||
}
|
||||
mscore->play(note->chord());
|
||||
adjustCanvasPosition(note, false);
|
||||
}
|
||||
}
|
||||
// not sure this 'else' is ever executed: test in line 5232 entered entry mode, if it was not active already
|
||||
else {
|
||||
Element* e = _score->selection().element();
|
||||
if (e && e->type() == NOTE) {
|
||||
Note* note = static_cast<Note*>(e);
|
||||
Chord* chord = note->chord();
|
||||
int key = _score->staff(chord->staffIdx())->key(chord->segment()->tick()).accidentalType();
|
||||
int newTpc = pitch2tpc(pitch, key);
|
||||
_score->undoChangePitch(note, pitch, newTpc, note->line()/*, note->fret(), note->string()*/);
|
||||
// Chord* chord = note->chord();
|
||||
// int key = _score->staff(chord->staffIdx())->key(chord->segment()->tick()).accidentalType();
|
||||
// int newTpc = pitch2tpc(pitch, key);
|
||||
// _score->undoChangePitch(note, pitch, newTpc, note->line());
|
||||
// we already computed right pitch and tpc
|
||||
_score->undoChangePitch(note, pitch, tpc, note->line());
|
||||
}
|
||||
}
|
||||
_score->endCmd();
|
||||
|
|
|
@ -238,7 +238,7 @@ class ScoreView : public QWidget, public MuseScoreView {
|
|||
void figuredBassEndEdit();
|
||||
void cmdInsertNote(int note);
|
||||
void cmdAddPitch(int note, bool addFlag);
|
||||
void cmdAddPitch1(int, bool);
|
||||
void cmdAddPitch1(int, bool, int step);
|
||||
void cmdAddChordName();
|
||||
void cmdAddText(int style);
|
||||
void cmdEnterRest(const TDuration&);
|
||||
|
|
Loading…
Reference in a new issue