Skip to content

Commit

Permalink
Merge pull request #432 from MarcSabatella/kbd-mode
Browse files Browse the repository at this point in the history
vertical keyboard navigation
  • Loading branch information
wschweer committed Aug 6, 2013
2 parents 4b6998a + c2225d7 commit 437a0dc
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 57 deletions.
20 changes: 17 additions & 3 deletions libmscore/cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1688,7 +1688,7 @@ Element* Score::move(const QString& cmd)
// retrieve last element of section list
if (!selection().elements().isEmpty())
el = selection().elements().last();
if(!el) // no element, no party!
if (!el) // no element, no party!
return 0;
// get parent of element and process accordingly:
// trg is the element to select on "next-chord" cmd
Expand Down Expand Up @@ -1744,7 +1744,7 @@ Element* Score::move(const QString& cmd)
return trg;
}
// if no chordrest found, do nothing
if(cr == 0)
if (cr == 0)
return 0;
// if some chordrest found, continue with default processing
}
Expand Down Expand Up @@ -1795,9 +1795,23 @@ Element* Score::move(const QString& cmd)
moveInputPos(crc->segment());
}
}
else if (cmd == "next-track") {
el = nextTrack(cr);
if (noteEntryMode() && el && (el->type() == Element::CHORD || el->type() == Element::REST)){
ChordRest* crc = static_cast<ChordRest*>(el);
moveInputPos(crc->segment());
}
}
else if (cmd == "prev-track") {
el = prevTrack(cr);
if (noteEntryMode() && el && (el->type() == Element::CHORD || el->type() == Element::REST)){
ChordRest* crc = static_cast<ChordRest*>(el);
moveInputPos(crc->segment());
}
}
if (el) {
if (el->type() == Element::CHORD)
el = static_cast<Chord*>(el)->downNote();
el = static_cast<Chord*>(el)->upNote(); // originally downNote
_playNote = true;
select(el, SELECT_SINGLE, 0);
}
Expand Down
160 changes: 108 additions & 52 deletions libmscore/navigate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,43 +119,37 @@ static bool noteLessThan(const Note* n1, const Note* n2)

//---------------------------------------------------------
// upAlt
// select next higher pitched note in chord
// return next higher pitched note in chord
// move to previous track if at top of chord
//---------------------------------------------------------

Note* Score::upAlt(Element* element)
ChordRest* Score::upAlt(Element* element)
{
Element* re = 0;
if (element->type() == Element::REST) {
if (_is.track() <= 0)
return 0;
_is.setTrack(_is.track() - 1);
re = searchNote(static_cast<Rest*>(element)->tick(), _is.track());
Rest* rest = static_cast<Rest*>(element);
re = prevTrack(rest);
}
else if (element->type() == Element::NOTE) {
// find segment
Chord* chord = static_cast<Note*>(element)->chord();
Segment* segment = chord->segment();

// collect all notes for this segment in noteList:
QList<Note*> rnl;
int tracks = nstaves() * VOICES;
for (int track = 0; track < tracks; ++track) {
Element* el = segment->element(track);
if (!el || el->type() != Element::CHORD)
continue;
rnl.append(static_cast<Chord*>(el)->notes());
qSort(rnl.begin(), rnl.end(), noteLessThan);
int idx = rnl.indexOf(static_cast<Note*>(element));
if (idx < rnl.size()-1)
++idx;
re = rnl.value(idx);
Chord* chord = static_cast<Note*>(element)->chord();
QList<Note*> notes = chord->notes();
// qSort(notes.begin(), notes.end(), noteLessThan);
int idx = notes.indexOf(static_cast<Note*>(element));
if (idx < notes.size()-1) {
++idx;
re = notes.value(idx);
}
else {
re = prevTrack(chord);
if (re->track() == chord->track())
re = element;
}
}
if (re == 0)
return 0;
if (re->type() == Element::CHORD)
re = ((Chord*)re)->notes().front();
return (Note*)re;
return (ChordRest*)re;
}

//---------------------------------------------------------
Expand All @@ -170,46 +164,37 @@ Note* Score::upAltCtrl(Note* note) const

//---------------------------------------------------------
// downAlt
// goto next note with lower pitch in chord or to
// top note in next staff
// return next lower pitched note in chord
// move to previous track if at bottom of chord
//---------------------------------------------------------

Note* Score::downAlt(Element* element)
ChordRest* Score::downAlt(Element* element)
{
Element* re = 0;
int staves = nstaves();
if (element->type() == Element::REST) {
if ((_is.track() + 1) >= staves * VOICES)
return 0;
_is.setTrack(_is.track() + 1);
re = searchNote(static_cast<Rest*>(element)->tick(), _is.track());
Rest* rest = static_cast<Rest*>(element);
re = nextTrack(rest);
}
else if (element->type() == Element::NOTE) {
// find segment
Chord* chord = static_cast<Note*>(element)->chord();
Segment* segment = chord->segment();

// collect all notes for this segment in noteList:
QList<Note*> rnl;
int tracks = nstaves() * VOICES;
for (int track = 0; track < tracks; ++track) {
Element* el = segment->element(track);
if (!el || el->type() != Element::CHORD)
continue;
rnl.append(static_cast<Chord*>(el)->notes());
qSort(rnl.begin(), rnl.end(), noteLessThan);
int idx = rnl.indexOf(static_cast<Note*>(element));
if (idx)
--idx;
re = rnl.value(idx);
Chord* chord = static_cast<Note*>(element)->chord();
QList<Note*> notes = chord->notes();
// qSort(notes.begin(), notes.end(), noteLessThan);
int idx = notes.indexOf(static_cast<Note*>(element));
if (idx > 0) {
--idx;
re = notes.value(idx);
}
else {
re = nextTrack(chord);
if (re->track() == chord->track())
re = element;
}
}

if (re == 0)
return 0;
if (re->type() == Element::CHORD)
re = static_cast<Chord*>(re)->notes().back();
return (Note*)re;
re = ((Chord*)re)->notes().back();
return (ChordRest*)re;
}

//---------------------------------------------------------
Expand Down Expand Up @@ -269,6 +254,77 @@ ChordRest* Score::downStaff(ChordRest* cr)
return 0;
}

//---------------------------------------------------------
// nextTrack
// returns note at or just before current (cr) position
// in next track for this measure
// that contains such an element
//---------------------------------------------------------

ChordRest* Score::nextTrack(ChordRest* cr)
{
if (!cr)
return 0;

Element* el = 0;
Measure* measure = cr->measure();
int track = cr->track();
int tracks = nstaves() * VOICES;

while (!el) {
// find next non-empty track
while (++track < tracks){
if (measure->hasVoice(track))
break;
}
// no more tracks, return original element
if (track == tracks)
return cr;
// find element at same or previous segment within this track
for (Segment* segment = cr->segment(); segment != 0; segment = segment->prev(Segment::SegChordRest)) {
el = segment->element(track);
if (el)
break;
}
}
return static_cast<ChordRest*>(el);
}

//---------------------------------------------------------
// prevTrack
// returns ChordRest at or just before current (cr) position
// in previous track for this measure
// that contains such an element
//---------------------------------------------------------

ChordRest* Score::prevTrack(ChordRest* cr)
{
if (!cr)
return 0;

Element* el = 0;
Measure* measure = cr->measure();
int track = cr->track();

while (!el) {
// find next non-empty track
while (--track >= 0){
if (measure->hasVoice(track))
break;
}
// no more tracks, return original element
if (track < 0)
return cr;
// find element at same or previous segment within this track
for (Segment* segment = cr->segment(); segment != 0; segment = segment->prev(Segment::SegChordRest)) {
el = segment->element(track);
if (el)
break;
}
}
return static_cast<ChordRest*>(el);
}

//---------------------------------------------------------
// nextMeasure
//---------------------------------------------------------
Expand Down
6 changes: 4 additions & 2 deletions libmscore/score.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,12 +363,14 @@ class Score : public QObject {
void cmdSetBeamMode(BeamMode);
void cmdFlip();
Note* getSelectedNote();
Note* upAlt(Element*);
ChordRest* upAlt(Element*);
Note* upAltCtrl(Note*) const;
Note* downAlt(Element*);
ChordRest* downAlt(Element*);
Note* downAltCtrl(Note*) const;
ChordRest* upStaff(ChordRest* cr);
ChordRest* downStaff(ChordRest* cr);
ChordRest* nextTrack(ChordRest* cr);
ChordRest* prevTrack(ChordRest* cr);
void moveUp(Chord*);
void moveDown(Chord*);

Expand Down
12 changes: 12 additions & 0 deletions mscore/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,12 @@ Shortcut Shortcut::sc[] = {
"prev-measure",
QT_TRANSLATE_NOOP("action","Previous measure")
),
Shortcut(
STATE_NORMAL | STATE_NOTE_ENTRY,
0,
"prev-track",
QT_TRANSLATE_NOOP("action","Previous staff or voice")
),
Shortcut(
STATE_NORMAL | STATE_NOTE_ENTRY,
0,
Expand All @@ -636,6 +642,12 @@ Shortcut Shortcut::sc[] = {
"next-measure",
QT_TRANSLATE_NOOP("action","Next measure")
),
Shortcut(
STATE_NORMAL | STATE_NOTE_ENTRY,
0,
"next-track",
QT_TRANSLATE_NOOP("action","Next staff or voice")
),
Shortcut(
STATE_NORMAL,
0,
Expand Down
2 changes: 2 additions & 0 deletions mscore/scoreview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2498,6 +2498,8 @@ void ScoreView::cmd(const QAction* a)
}
else if (cmd == "next-chord"
|| cmd == "prev-chord"
|| cmd == "next-track"
|| cmd == "prev-track"
|| cmd == "next-measure"
|| cmd == "prev-measure") {
Element* el = score()->selection().element();
Expand Down

0 comments on commit 437a0dc

Please sign in to comment.