Merge branch 'new_note_input_method' of https://github.com/mgavioli/MuseScore into noteentry

This commit is contained in:
Werner Schweer 2012-08-06 12:26:13 +02:00
commit 69c0b17495
2 changed files with 111 additions and 10 deletions

View file

@ -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();

View file

@ -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&);