diff options
author | Florian Jung <flo@windfisch.org> | 2011-04-12 15:04:11 +0000 |
---|---|---|
committer | Florian Jung <flo@windfisch.org> | 2011-04-12 15:04:11 +0000 |
commit | 585c061fe77c03bb108c9f56671068a061498535 (patch) | |
tree | abaa5088e742f867810848dfb37607e1c9d78808 /muse2/muse | |
parent | 533f81167c006932a3bd7d95c62abbbd59157228 (diff) |
introduced keymap, fixed all the ugly stuff from the last commit
Diffstat (limited to 'muse2/muse')
-rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 112 | ||||
-rw-r--r-- | muse2/muse/midiedit/scoreedit.h | 38 |
2 files changed, 118 insertions, 32 deletions
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index c7e68f0b..94baad4c 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -97,6 +97,37 @@ using namespace std; #define STAFF_DISTANCE 100 + +KeyList keymap; + + + +KeyList::KeyList() +{ + clear(); +} + +void KeyList::clear() +{ + _KeyList::clear(); //DEBUG -- remove these lines and use the commented out below + insert(std::pair<const unsigned, KeyEvent> (1536, KeyEvent(A, 0))); + insert(std::pair<const unsigned, KeyEvent> (MAX_TICK, KeyEvent(ES, 1536))); + + //insert(std::pair<const unsigned, KeyEvent> (MAX_TICK, KeyEvent(A, 0))); +} + +tonart_t KeyList::key_at_tick(unsigned tick) +{ + ciKeyEvent it = upper_bound(tick); + if (it == end()) + { + cout << "THIS SHOULD NEVER HAPPEN: key at "<<tick<<" not found!" << endl; + return C; + } + + return it->second.key; +} + //--------------------------------------------------------- // ScoreEdit //--------------------------------------------------------- @@ -218,9 +249,11 @@ ScoreCanvas::ScoreCanvas(MidiEditor* pr, QWidget* parent, void ScoreCanvas::song_changed(int) { cout << "song changed!" << endl; + + calc_pos_add_list(); + for (list<staff_t>::iterator it=staffs.begin(); it!=staffs.end(); it++) { - pos_add_list.clear(); //FINDMICHJETZT schöner machen it->eventlist=create_appropriate_eventlist(it->parts); it->itemlist=create_itemlist(it->eventlist); process_itemlist(it->itemlist); // do note- and rest-grouping and collision avoiding @@ -449,10 +482,9 @@ ScoreEventList ScoreCanvas::create_appropriate_eventlist(const set<Part*>& parts result.insert(pair<unsigned, FloEvent>(t, FloEvent(t,0,0,ticks_per_measure,FloEvent::BAR) ) ); } - - //TODO FINDMICH MARKER - result.insert(pair<unsigned, FloEvent>(0, FloEvent(0,FloEvent::KEY_CHANGE, A ) ) ); - result.insert(pair<unsigned, FloEvent>(4*384, FloEvent(4*384,FloEvent::KEY_CHANGE, ES ) ) ); + //insert key changes + for (iKeyEvent it=keymap.begin(); it!=keymap.end(); it++) + result.insert(pair<unsigned, FloEvent>(it->second.tick, FloEvent(it->second.tick,FloEvent::KEY_CHANGE, it->second.key ) ) ); // phase two: deal with overlapping notes --------------------------- @@ -1578,9 +1610,6 @@ void ScoreCanvas::calc_item_pos(ScoreItemList& itemlist) { int add=calc_timesig_width(it->num, it->denom); pos_add+=add; - pos_add_list[it2->first]+=add; - //+= is used instead of =, because a key- and time- - //change can occur at the same time. } else if (it->type==FloItem::KEY_CHANGE) { @@ -1591,9 +1620,6 @@ void ScoreCanvas::calc_item_pos(ScoreItemList& itemlist) int n_acc_drawn=aufloes_list.size() + new_acc_list.size(); pos_add+=n_acc_drawn*KEYCHANGE_ACC_DIST+ KEYCHANGE_ACC_LEFTDIST+ KEYCHANGE_ACC_RIGHTDIST; - pos_add_list[it2->first]+=n_acc_drawn*KEYCHANGE_ACC_DIST+ KEYCHANGE_ACC_LEFTDIST+ KEYCHANGE_ACC_RIGHTDIST; - //+= is used instead of =, because a key- and time- - //change can occur at the same time. curr_key=new_key; } @@ -1601,12 +1627,39 @@ void ScoreCanvas::calc_item_pos(ScoreItemList& itemlist) } } +void ScoreCanvas::calc_pos_add_list() +{ + using AL::sigmap; + using AL::iSigEvent; + + + pos_add_list.clear(); + + //process time signatures + for (iSigEvent it=sigmap.begin(); it!=sigmap.end(); it++) + pos_add_list[it->second->tick]+=calc_timesig_width(it->second->sig.z, it->second->sig.n); + + + //process key changes + tonart_t curr_key=C; + for (iKeyEvent it=keymap.begin(); it!=keymap.end(); it++) + { + tonart_t new_key=it->second.key; + list<int> aufloes_list=calc_accidentials(curr_key, USED_CLEF, new_key); + list<int> new_acc_list=calc_accidentials(new_key, USED_CLEF); + int n_acc_drawn=aufloes_list.size() + new_acc_list.size(); + pos_add_list[it->second.tick]+=n_acc_drawn*KEYCHANGE_ACC_DIST+ KEYCHANGE_ACC_LEFTDIST+ KEYCHANGE_ACC_RIGHTDIST; + + curr_key=new_key; + } +} + void ScoreCanvas::draw_items(QPainter& p, int y, ScoreItemList& itemlist, int x1, int x2) { int from_tick, to_tick; ScoreItemList::iterator from_it, to_it; - //in general: drawing too much isn't bad. drawing too few is. + //drawing too much isn't bad. drawing too few is. from_tick=x_to_tick(x1); from_it=itemlist.lower_bound(from_tick); @@ -2129,30 +2182,20 @@ int ScoreCanvas::x_to_tick(int x) return t > min_t ? t : min_t; } -tonart_t ScoreCanvas::key_at_tick(int t_) //FINDMICHJETZT besser lösen! nur übergangslösung! +tonart_t ScoreCanvas::key_at_tick(int t_) { - tonart_t tmp; unsigned int t= (t_>=0) ? t_ : 0; - for (ScoreEventList::iterator it=staffs.begin()->eventlist.begin(); it!=staffs.begin()->eventlist.end() && it->first<=t; it++) - if (it->second.type==FloEvent::KEY_CHANGE) - tmp=it->second.tonart; - - return tmp; + return keymap.key_at_tick(t); } -timesig_t ScoreCanvas::timesig_at_tick(int t_) //FINDMICHJETZT besser lösen! nur übergangslösung! +timesig_t ScoreCanvas::timesig_at_tick(int t_) { timesig_t tmp; unsigned int t= (t_>=0) ? t_ : 0; - for (ScoreEventList::iterator it=staffs.begin()->eventlist.begin(); it!=staffs.begin()->eventlist.end() && it->first<=t; it++) - if (it->second.type==FloEvent::TIME_SIG) - { - tmp.num=it->second.num; - tmp.denom=it->second.denom; - } - + AL::sigmap.timesig(t, tmp.num, tmp.denom); + return tmp; } @@ -2591,12 +2634,14 @@ void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll) /* BUGS and potential bugs + * o when adding a note, it's added to the first stave + * the problem is: there's always the first part selected * o when changing color of a displayed part, note heads aren't redrawn * o when pressing "STOP", the active note isn't redrawn "normally" * * CURRENT TODO * o menu entries etc for creating new staves etc. - * o proper mouse.y -> staff_no translation + * o proper mouse.y -> staff_no translation (plus rounding problems) * * IMPORTANT TODO * o support adding staves to existing score window @@ -2615,6 +2660,11 @@ void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll) * o check if "moving away" works for whole notes [seems to NOT work properly] * * less important stuff + * o support different keys in different tracks at the same time + * calc_pos_add_list and calc_item_pos will be affected by this + * calc_pos_add_list must be called before calc_item_pos then, + * and calc_item_pos must respect the pos_add_list instead of + * keeping its own pos_add variable (which is only an optimisation) * o use nearest part instead of curr_part, maybe expand * o draw measure numbers * o use "unsigned" whereever "unsigned" is meant @@ -2631,7 +2681,7 @@ void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll) * o let the user select whether the preamble should have * a fixed length (?) * o let the user select what the preamble has to contain - * o use timesig_t in all timesig-stuff + * > o use timesig_t in all timesig-stuff * o draw a margin around notes which are in a bright color * o maybe override color 0 with "black"? * o use bars instead of flags over groups of 8ths / 16ths etc @@ -2642,16 +2692,16 @@ void ScoreCanvas::pos_changed(int index, unsigned tick, bool scroll) * o check if the new function for drawing accidential works * o refuse to resize so that width gets smaller or equal than x_left * o set distances properly [looks okay, doesn't it?] - * o maybe eliminate all the compiler warnings * o change iterators into const iterators * o add tracks in correct order to score * * stuff for the other muse developers + * o OFFER A WAY TO EDIT THE KEYMAP (and integrate the keymap properly) + * * o check if dragging notes is done correctly * o after doing the undo stuff right, the "pianoroll isn't informed * about score-editor's changes"-bug has vanished. did it vanish * "by accident", or is that the correct solution for this? - * o process key from muse's event list (has to be implemented first in muse) * o process accurate timesignatures from muse's list (has to be implemented first in muse) * ( (2+2+3)/4 or (3+2+2)/4 instead of 7/4 ) * o maybe do expanding parts inside the msgChangeEvent or diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index 84a74cb0..95dde6c2 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -65,6 +65,11 @@ class QScrollArea; + + + + + //--------------------------------------------------------- // ScoreEdit //--------------------------------------------------------- @@ -147,6 +152,37 @@ struct note_pos_t bool operator< (const note_pos_t& a, const note_pos_t& b); + +// FINDMICH put that keymap-stuff to its appropriate place +struct KeyEvent +{ + tonart_t key; + unsigned tick; + + KeyEvent(tonart_t k, unsigned t) + { + key=k; + tick=t; + } +}; + +typedef std::map<unsigned, KeyEvent, std::less<unsigned> > _KeyList; +typedef _KeyList::iterator iKeyEvent; +typedef _KeyList::const_iterator ciKeyEvent; +typedef _KeyList::reverse_iterator riKeyEvent; +typedef _KeyList::const_reverse_iterator criKeyEvent; + +class KeyList : public _KeyList +{ + public: + KeyList(); + void clear(); + tonart_t key_at_tick(unsigned tick); + //TODO FINDMICH: more functions, like add(), remove() have to be implemented +}; + + + class FloEvent { public: @@ -467,7 +503,7 @@ class ScoreCanvas : public View void draw_items(QPainter& p, int y, ScoreItemList& itemlist, int x1, int x2); void draw_items(QPainter& p, int y, ScoreItemList& itemlist); void calc_item_pos(ScoreItemList& itemlist); - + void calc_pos_add_list(); |