diff options
author | Florian Jung <flo@windfisch.org> | 2011-04-10 15:26:44 +0000 |
---|---|---|
committer | Florian Jung <flo@windfisch.org> | 2011-04-10 15:26:44 +0000 |
commit | aa9289e97922c1690587fb52a35483db95c93e9a (patch) | |
tree | 2d0546fa128c45aaeb88ff11428c93dd11a6e268 | |
parent | 38f3da79d43eef049574f6d332b78e7d43a57004 (diff) |
inserting notes and undo handling now works
plus bugfix: event times are now treated correctly
-rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 139 | ||||
-rw-r--r-- | muse2/muse/midiedit/scoreedit.h | 11 |
2 files changed, 134 insertions, 16 deletions
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 44f80263..1a264030 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -145,6 +145,12 @@ ScoreCanvas::ScoreCanvas(MidiEditor* pr, QWidget* parent, x_pos=0; dragging=false; mouse_erases_notes=false; + mouse_inserts_notes=true; + + curr_part=editor->parts()->begin()->second; + + last_len=384; + new_len=-1; song_changed(0); //fertig mit aufbereiten @@ -280,8 +286,8 @@ ScoreEventList ScoreCanvas::createAppropriateEventList(PartList* pl, Track* trac if (event.isNote() && !event.isNoteOff()) { unsigned begin, end; - begin=flo_quantize(event.tick()); - end=flo_quantize(event.endTick()); + begin=flo_quantize(event.tick()+part->tick()); + end=flo_quantize(event.endTick()+part->tick()); cout <<"inserting note on at "<<begin<<" with pitch="<<event.pitch()<<" and len="<<end-begin<<endl; cout<< "\tinserting corresponding note off at "<<endl; result.insert(pair<unsigned, FloEvent>(begin, FloEvent(begin,event.pitch(), event.velo(),end-begin,FloEvent::NOTE_ON,part,&it->second))); @@ -1789,6 +1795,55 @@ int ScoreCanvas::x_to_tick(int x) return t > min_t ? t : min_t; } +tonart_t ScoreCanvas::key_at_tick(int t) +{ + tonart_t tmp; + for (ScoreEventList::iterator it=eventlist.begin(); it!=eventlist.end() && it->first<=t; it++) + if (it->second.type==FloEvent::KEY_CHANGE) + tmp=it->second.tonart; + + return tmp; +} + +int ScoreCanvas::height_to_pitch(int h) +{ + int foo[]={0,2,4,5,7,9,11}; + + return foo[modulo(h,7)] + ( (h/7)*12 ) + 60; +} + +int ScoreCanvas::height_to_pitch(int h, tonart_t key) +{ + int add=0; + + int sharp_pos[]={10,7,11,8,5,9,6}; //TODO merge with draw function (where drawing accidentials) + int b_pos[]={6,9,5,8,4,7,3}; + + int* acc_ptr = is_sharp_key(key) ? sharp_pos : b_pos; + + for (int i=0;i<n_accidentials(key);i++) + { + if (modulo(acc_ptr[i],7) == modulo(h,7)) + { + add=is_sharp_key(key) ? 1 : -1; + break; + } + } + + return height_to_pitch(h)+add; +} + +int ScoreCanvas::y_to_height(int y) +{ + //Y_MARKER + return int(rint(float(YDIST+4*YLEN - y)*2/YLEN))+2 ; +} + +int ScoreCanvas::y_to_pitch(int y, int t) +{ + return height_to_pitch(y_to_height(y), key_at_tick(t)); +} + #define DRAG_INIT_DISTANCE 5 @@ -1876,25 +1931,66 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event) { setMouseTracking(true); dragging=true; + song->startUndo(); + } + } + else //we found nothing? + { + if ((event->button()==Qt::LeftButton) && (mouse_inserts_notes)) + { + song->startUndo(); + //stopping undo at the end of this function is unneccessary + //because we'll begin a drag right after it. finishing + //this drag will stop undo as well (in mouseReleaseEvent) + + Event newevent(Note); + newevent.setPitch(y_to_pitch(y,tick)); + newevent.setVelo(64); //TODO + newevent.setVeloOff(64); //TODO + newevent.setTick(tick); + newevent.setLenTick((new_len>0)?new_len:last_len); + + audio->msgAddEvent(newevent, curr_part, false, false, false); + + dragged_event_part=curr_part; + dragged_event=newevent; + dragged_event_original_pitch=newevent.pitch(); + + mouse_down_pos=event->pos(); + mouse_operation=NO_OP; + mouse_x_drag_operation=LENGTH; + + setMouseTracking(true); + dragging=true; + //song->startUndo(); unneccessary because we have started it already above } } + } void ScoreCanvas::mouseReleaseEvent (QMouseEvent* event) { if (event->button()==Qt::LeftButton) { - if (dragging && mouse_operation==LENGTH) + if (dragging) { - if (flo_quantize(dragged_event.lenTick()) <= 0) + if (mouse_operation==LENGTH) { - cout << "new length <= 0, erasing item" << endl; - audio->msgDeleteEvent(dragged_event, dragged_event_part, true, false, false); + if (flo_quantize(dragged_event.lenTick()) <= 0) + { + cout << "new length <= 0, erasing item" << endl; + audio->msgDeleteEvent(dragged_event, dragged_event_part, false, false, false); + } + else + { + last_len=flo_quantize(dragged_event.lenTick()); + } } + + song->endUndo(SC_EVENT_MODIFIED); + setMouseTracking(false); + dragging=false; } - - setMouseTracking(false); - dragging=false; } } @@ -2022,29 +2118,40 @@ void ScoreCanvas::scroll_event(int x) // every time something changes. -/* IMPORTANT TODO - * o support inserting notes +/* BUGS and potential bugs + * o bass-clef (and all other clefs than the violin-clef) will + * cause strange behaviour, for example when drawing accidentials, + * calling y_to_pitch etc. + * o when dividing, use a function which always rounds downwards + * operator/ rounds towards zero. (-5)/7=0, but should be -1 + * + * IMPORTANT TODO + * o removing the part the score's working on isn't handled + * * o let the user select the currently edited part - * o BUG: selecting multiple parts causes weird behaviour * * o use a function for drawing timesig changes. support two(or more)-digit-numbers * o create nice functions for drawing keychange-accidentials * o draw clef, maybe support clef changes. support violin and bass at one time - * o support undo when doing stuff * o eliminate overlapping notes (e.g. C from 0 with len=10 and C from 5 with len=10) * * less important stuff - * o check if "moving away" works for whole notes + * o check if "moving away" works for whole notes [seems to NOT work properly] * o use bars instead of flags over groups of 8ths / 16ths etc * o (change ItemList into map< pos_t , mutable_stuff_t >) [no] * o deal with expanding parts or clip (expanding is better) * * stuff for the other muse developers - * o check if dragging notes works correctly (the pianoroll seems to be not informed :/ ) + * 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 ) * * GUI stuff - * o offer a button for bool mouse_erases_notes + * o offer a button for bool mouse_erases_notes and mouse_inserts_notes + * o offer dropdown-boxes for lengths of the inserted note + * (select between 16th, 8th, ... whole and "last used length") */ diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index d8afa961..ab35e5b6 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -417,6 +417,12 @@ class ScoreCanvas : public View void draw_items(QPainter& p, ScoreItemList& itemlist); void calc_item_pos(ScoreItemList& itemlist); + int y_to_pitch(int y, int t); + int y_to_height(int y); + int height_to_pitch(int h, tonart_t key); + int height_to_pitch(int h); + + tonart_t key_at_tick(int t); int tick_to_x(int t); int x_to_tick(int x); int calc_posadd(int t); @@ -434,6 +440,10 @@ class ScoreCanvas : public View int x_pos; + Part* curr_part; + int last_len; + int new_len; //when zero or negative, last_len is used + QPoint mouse_down_pos; bool mouse_down; enum operation_t @@ -446,6 +456,7 @@ class ScoreCanvas : public View operation_t mouse_operation; operation_t mouse_x_drag_operation; bool mouse_erases_notes; + bool mouse_inserts_notes; bool dragging; Part* dragged_event_part; |