diff options
Diffstat (limited to 'muse2')
| -rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 310 | ||||
| -rw-r--r-- | muse2/muse/midiedit/scoreedit.h | 2 | 
2 files changed, 179 insertions, 133 deletions
| diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index d483b5e7..44f80263 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -74,6 +74,7 @@ using namespace std;  ScoreEdit::ScoreEdit(PartList* pl, QWidget* parent, const char* name, unsigned initPos)     : MidiEditor(0, 0, pl, parent, name)  { +	  //	Splitter* hsplitter;  	QPushButton* ctrl;  /*	 @@ -142,6 +143,8 @@ ScoreCanvas::ScoreCanvas(MidiEditor* pr, QWidget* parent,  	load_pixmaps();  	x_pos=0; +	dragging=false; +	mouse_erases_notes=false;  	song_changed(0);	  //fertig mit aufbereiten	 @@ -172,7 +175,6 @@ string IntToStr(int i) -#define FONT_PATH "/home/flo/AKTENKOFFER/programme/museueberlegungen/glyphs/"  void ScoreCanvas::load_pixmaps()  {  	pix_whole.load(FONT_PATH "whole.png"); @@ -243,6 +245,19 @@ bool operator< (const note_pos_t& a, const note_pos_t& b)   * this abstracts the rest of the renderer from muse's internal   * data structures, making this easy to port to another application   */ +  +int flo_quantize(int tick) +{ +	//TODO quantizing must be done with the proper functions! +	return int(rint((float)tick / FLO_QUANT))*FLO_QUANT; +} +  +int flo_quantize_floor(int tick) +{ +	//TODO quantizing must be done with the proper functions, see above +	return int(tick / FLO_QUANT) * FLO_QUANT; +} +   ScoreEventList ScoreCanvas::createAppropriateEventList(PartList* pl, Track* track)  {  	using AL::sigmap; @@ -265,9 +280,8 @@ ScoreEventList ScoreCanvas::createAppropriateEventList(PartList* pl, Track* trac  				if (event.isNote() && !event.isNoteOff())  				{  					unsigned begin, end; -					//TODO quantizing must be done with the proper functions! -					begin=int(rint((float)event.tick() / FLO_QUANT))*FLO_QUANT; -					end=int(rint((float)event.endTick() / FLO_QUANT))*FLO_QUANT; +					begin=flo_quantize(event.tick()); +					end=flo_quantize(event.endTick());  					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))); @@ -1786,161 +1800,185 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event)  	int y=event->y();  	int x=event->x()+x_pos; -	int tick= int(x_to_tick(x) / FLO_QUANT) * FLO_QUANT; +	int tick=flo_quantize_floor(x_to_tick(x));  						//TODO quantizing must (maybe?) be done with the proper functions  	cout << "mousePressEvent at "<<x<<"/"<<y<<"; tick="<<tick<<endl; -	 -	for (set<FloItem, floComp>::iterator it=itemlist[tick].begin(); it!=itemlist[tick].end(); it++) +	set<FloItem, floComp>::iterator it; +	for (it=itemlist[tick].begin(); it!=itemlist[tick].end(); it++)  		if (it->type==FloItem::NOTE)  			if (it->bbox().contains(x,y)) +				break; +	 +	if (it!=itemlist[tick].end()) //we found something? +	{ +		mouse_down_pos=event->pos(); +		mouse_operation=NO_OP; +		 +		int t=tick; +		set<FloItem, floComp>::iterator found; +		 +		do +		{ +			found=itemlist[t].find(FloItem(FloItem::NOTE, it->pos)); +			if (found == itemlist[t].end())  			{ -				mouse_down_pos=event->pos(); -				mouse_operation=NO_OP; -				 -				int t=tick; -				set<FloItem, floComp>::iterator found; -				 -				do -				{ -					found=itemlist[t].find(FloItem(FloItem::NOTE, it->pos)); -					if (found == itemlist[t].end()) -					{ -						cout << "FATAL: THIS SHOULD NEVER HAPPEN: could not find the note's tie-destination" << endl; -						break; -					} -					else -					{ -						t+=calc_len(found->len, found->dots); -					} -				} while (found->tied); -				 -				int total_begin=it->begin_tick; -				int total_end=t; -				 -				int this_begin=tick; -				int this_end=this_begin+calc_len(it->len, it->dots); -				 -				//that's the only note corresponding to the event? -				if (this_begin==total_begin && this_end==total_end) -				{ -					if (x < it->x) -						mouse_x_drag_operation=BEGIN; -					else -						mouse_x_drag_operation=LENGTH; -				} -				//that's NOT the only note? -				else -				{ -					if (this_begin==total_begin) -						mouse_x_drag_operation=BEGIN; -					else if (this_end==total_end) -						mouse_x_drag_operation=LENGTH; -					else -						mouse_x_drag_operation=NO_OP; -				} -				 -				cout << "you clicked at a note with begin at "<<it->begin_tick<<" and end at "<<t<<endl; -				cout << "x-drag-operation will be "<<mouse_x_drag_operation<<endl; -				cout << "pointer to part is "<<it->source_part; -				if (!it->source_part) cout << " (WARNING! THIS SHOULD NEVER HAPPEN!)"; -				cout << endl; -				 -				dragged_event=*it->source_event; -				dragged_event_part=it->source_part; -				dragged_event_original_pitch=dragged_event.pitch(); -				 -				setMouseTracking(true); -				 +				cout << "FATAL: THIS SHOULD NEVER HAPPEN: could not find the note's tie-destination" << endl;  				break;  			} -	 +			else +			{ +				t+=calc_len(found->len, found->dots); +			} +		} while (found->tied); +		 +		int total_begin=it->begin_tick; +		int total_end=t; +		 +		int this_begin=tick; +		int this_end=this_begin+calc_len(it->len, it->dots); +		 +		//that's the only note corresponding to the event? +		if (this_begin==total_begin && this_end==total_end) +		{ +			if (x < it->x) +				mouse_x_drag_operation=BEGIN; +			else +				mouse_x_drag_operation=LENGTH; +		} +		//that's NOT the only note? +		else +		{ +			if (this_begin==total_begin) +				mouse_x_drag_operation=BEGIN; +			else if (this_end==total_end) +				mouse_x_drag_operation=LENGTH; +			else +				mouse_x_drag_operation=NO_OP; +		} +		 +		cout << "you clicked at a note with begin at "<<it->begin_tick<<" and end at "<<t<<endl; +		cout << "x-drag-operation will be "<<mouse_x_drag_operation<<endl; +		cout << "pointer to part is "<<it->source_part; +		if (!it->source_part) cout << " (WARNING! THIS SHOULD NEVER HAPPEN!)"; +		cout << endl; +		 +		dragged_event=*it->source_event; +		dragged_event_part=it->source_part; +		dragged_event_original_pitch=dragged_event.pitch(); +		 +		if ((mouse_erases_notes) || (event->button()==Qt::MidButton)) //erase? +		{ +			audio->msgDeleteEvent(dragged_event, dragged_event_part, true, false, false); +		} +		else if (event->button()==Qt::LeftButton) //edit? +		{ +			setMouseTracking(true);		 +			dragging=true; +		} +	}  }  void ScoreCanvas::mouseReleaseEvent (QMouseEvent* event)  { -	setMouseTracking(false); +	if (event->button()==Qt::LeftButton) +	{ +		if (dragging && mouse_operation==LENGTH) +		{ +			if (flo_quantize(dragged_event.lenTick()) <= 0) +			{ +				cout << "new length <= 0, erasing item" << endl; +				audio->msgDeleteEvent(dragged_event, dragged_event_part, true, false, false); +			} +		} +		 +		setMouseTracking(false); +		dragging=false; +	}  }  #define PITCH_DELTA 5  void ScoreCanvas::mouseMoveEvent (QMouseEvent* event)  { -	int dx=event->x()-mouse_down_pos.x(); -	int dy=event->y()-mouse_down_pos.y(); - -	int y=event->y(); -	int x=event->x()+x_pos; -	int tick= int(x_to_tick(x) / FLO_QUANT) * FLO_QUANT; - -	if (mouse_operation==NO_OP) -	{		 -		if ((abs(dx)>DRAG_INIT_DISTANCE) && (mouse_x_drag_operation!=NO_OP)) -		{ -			cout << "mouse-operation is now "<<mouse_x_drag_operation<<endl; -			mouse_operation=mouse_x_drag_operation; -		} -		else if (abs(dy)>DRAG_INIT_DISTANCE) -		{ -			cout << "mouse-operation is now PITCH" << endl; -			mouse_operation=PITCH; -		} -	} - -	int new_pitch; -	 -	switch (mouse_operation) +	if (dragging)  	{ -		case NONE: -			break; -			 -		case PITCH: -			cout << "changing pitch, delta="<<dy/PITCH_DELTA<<endl; -			new_pitch=dragged_event_original_pitch - dy/PITCH_DELTA; +		int dx=event->x()-mouse_down_pos.x(); +		int dy=event->y()-mouse_down_pos.y(); -			if (dragged_event.pitch()!=new_pitch) +		int y=event->y(); +		int x=event->x()+x_pos; +		int tick=flo_quantize_floor(x_to_tick(x)); + +		if (mouse_operation==NO_OP) +		{		 +			if ((abs(dx)>DRAG_INIT_DISTANCE) && (mouse_x_drag_operation!=NO_OP))  			{ -				Event tmp=dragged_event.clone(); -				tmp.setPitch(dragged_event_original_pitch- dy/PITCH_DELTA); -				 -				audio->msgChangeEvent(dragged_event, tmp, dragged_event_part, false, false, false); -				dragged_event=tmp; -				 -				song_changed(0);	 +				cout << "mouse-operation is now "<<mouse_x_drag_operation<<endl; +				mouse_operation=mouse_x_drag_operation;  			} -			 -			break; -		 -		case BEGIN: -			if (dragged_event.tick() != tick) +			else if (abs(dy)>DRAG_INIT_DISTANCE)  			{ -				Event tmp=dragged_event.clone(); -				tmp.setTick(tick); -				 -				audio->msgChangeEvent(dragged_event, tmp, dragged_event_part, false, false, false); -				dragged_event=tmp; -				 -				song_changed(0);	 +				cout << "mouse-operation is now PITCH" << endl; +				mouse_operation=PITCH;  			} -			 -			break; +		} -		case LENGTH: -			tick+=FLO_QUANT; -			if (dragged_event.tick()+dragged_event.lenTick() != tick) -			{ -				Event tmp=dragged_event.clone(); -				tmp.setLenTick(tick-dragged_event.tick()); +		int new_pitch; +		 +		switch (mouse_operation) +		{ +			case NONE: +				break; -				audio->msgChangeEvent(dragged_event, tmp, dragged_event_part, false, false, false); -				dragged_event=tmp; +			case PITCH: +				cout << "changing pitch, delta="<<dy/PITCH_DELTA<<endl; +				new_pitch=dragged_event_original_pitch - dy/PITCH_DELTA; + +				if (dragged_event.pitch()!=new_pitch) +				{ +					Event tmp=dragged_event.clone(); +					tmp.setPitch(dragged_event_original_pitch- dy/PITCH_DELTA); +					 +					audio->msgChangeEvent(dragged_event, tmp, dragged_event_part, false, false, false); +					dragged_event=tmp; +					 +					song_changed(0);	 +				} -				song_changed(0);	 -			} +				break; -			break; -	}	 +			case BEGIN: +				if (dragged_event.tick() != tick) +				{ +					Event tmp=dragged_event.clone(); +					tmp.setTick(tick); +					 +					audio->msgChangeEvent(dragged_event, tmp, dragged_event_part, false, false, false); +					dragged_event=tmp; +					 +					song_changed(0);	 +				} +				 +				break; + +			case LENGTH: +				tick+=FLO_QUANT; +				if (dragged_event.tick()+dragged_event.lenTick() != tick) +				{ +					Event tmp=dragged_event.clone(); +					tmp.setLenTick(tick-dragged_event.tick()); +					 +					audio->msgChangeEvent(dragged_event, tmp, dragged_event_part, false, false, false); +					dragged_event=tmp; +					 +					song_changed(0);	 +				} +				 +				break; +		}	 +	}  }  void ScoreCanvas::scroll_event(int x) @@ -1985,22 +2023,28 @@ void ScoreCanvas::scroll_event(int x)  /* IMPORTANT TODO + *   o support inserting notes + *   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 inserting notes - *   o support erasing notes (resize to len=0? watch out for quantisation stuff) - *   o support undo when dragging notes + *   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 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 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   */ diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index fbda4579..d8afa961 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -445,7 +445,9 @@ class ScoreCanvas : public View  		};  		operation_t mouse_operation;  		operation_t mouse_x_drag_operation; +		bool mouse_erases_notes; +		bool dragging;  		Part* dragged_event_part;  		Event dragged_event;  		int dragged_event_original_pitch; | 
