summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-04-10 15:26:44 +0000
committerFlorian Jung <flo@windfisch.org>2011-04-10 15:26:44 +0000
commitaa9289e97922c1690587fb52a35483db95c93e9a (patch)
tree2d0546fa128c45aaeb88ff11428c93dd11a6e268
parent38f3da79d43eef049574f6d332b78e7d43a57004 (diff)
inserting notes and undo handling now works
plus bugfix: event times are now treated correctly
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp139
-rw-r--r--muse2/muse/midiedit/scoreedit.h11
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;