diff options
| author | Florian Jung <flo@windfisch.org> | 2011-04-21 18:46:48 +0000 | 
|---|---|---|
| committer | Florian Jung <flo@windfisch.org> | 2011-04-21 18:46:48 +0000 | 
| commit | e544d366103630a39d72998bcef2e4970d0d0ea1 (patch) | |
| tree | 43cfe3f36ab7180f92943e74d9623791d9a15f0a | |
| parent | ba3b8723b9672bd42888da2e9f1f644393a46c39 (diff) | |
removing a currently shown part is now handled gracefully
the score window automatically closes if the last staff is removed
| -rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 106 | ||||
| -rw-r--r-- | muse2/muse/midiedit/scoreedit.h | 17 | 
2 files changed, 99 insertions, 24 deletions
| diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index e904ce46..143daac5 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -460,15 +460,16 @@ void ScoreCanvas::add_staves(PartList* pl, bool all_in_one)  		}  	} +	cleanup_staves();  	recalc_staff_pos();  	song_changed(SC_EVENT_INSERTED);  } -ScoreCanvas::ScoreCanvas(MidiEditor* pr, QWidget* parent, -   int sx, int sy) : View(parent, sx, sy) +ScoreCanvas::ScoreCanvas(MidiEditor* pr, QWidget* parent_widget, +   int sx, int sy) : View(parent_widget, sx, sy)  { -	editor      = pr; +	parent      = pr;  	setFocusPolicy(Qt::StrongFocus);  	setBg(Qt::white); @@ -483,7 +484,7 @@ ScoreCanvas::ScoreCanvas(MidiEditor* pr, QWidget* parent,  	mouse_erases_notes=false;  	mouse_inserts_notes=true; -	curr_part=editor->parts()->begin()->second; //TODO FINDMICHJETZT +	curr_part=parent->parts()->begin()->second; //TODO FINDMICHJETZT  	last_len=384;  	new_len=-1; @@ -614,6 +615,7 @@ void ScoreCanvas::remove_staff(list<staff_t>::iterator it)  		staves.erase(it);  	}		 +	maybe_close_if_empty();  	recalc_staff_pos();  	song_changed(SC_EVENT_INSERTED);  } @@ -657,26 +659,36 @@ void ScoreCanvas::merge_staves(list<staff_t>::iterator dest, list<staff_t>::iter  void ScoreCanvas::song_changed(int flags)  { -	if (flags & (SC_PART_INSERTED | SC_PART_MODIFIED | SC_PART_REMOVED | +	if (flags & (SC_PART_MODIFIED |  	             SC_EVENT_INSERTED | SC_EVENT_MODIFIED | SC_EVENT_REMOVED |  	             SC_SIG  | SC_KEY) )  	{ -		cout << "song changed!" << endl; -  		calc_pos_add_list();  		for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++) +			it->recalculate(); +		 +		redraw(); +		emit canvas_width_changed(canvas_width()); +	} +	 +	if (flags & SC_PART_REMOVED) +	{ +		bool something_changed=false; +		 +		for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++)  		{ -			it->create_appropriate_eventlist(it->parts); -			it->create_itemlist(); -			it->process_itemlist(); // do note- and rest-grouping and collision avoiding -			it->calc_item_pos(); +			if (it->cleanup_parts()) +				something_changed=true;  		} -		redraw(); -		cout << "song had changed, recalculation complete" << endl; +		cleanup_staves(); +		recalc_staff_pos(); -		emit canvas_width_changed(canvas_width()); +		for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++) +			it->recalculate(); + +		redraw();  	}  } @@ -860,7 +872,7 @@ int flo_quantize_floor(int tick, int quant_ticks)   * this abstracts the rest of the renderer from muse's internal   * data structures, making this easy to port to another application   */ -void staff_t::create_appropriate_eventlist(const set<Part*>& parts) +void staff_t::create_appropriate_eventlist()  {  	using AL::sigmap;  	using AL::iSigEvent; @@ -3213,7 +3225,61 @@ void ScoreCanvas::set_quant(int val)  	}  } +void ScoreCanvas::cleanup_staves() +{ +	for (list<staff_t>::iterator it=staves.begin(); it!=staves.end();) +	{ +		if (it->parts.empty()) +			staves.erase(it++); +		else +			it++; +	} +	 +	maybe_close_if_empty(); +} + +void ScoreCanvas::maybe_close_if_empty() +{ +	if (staves.empty()) +	{ +		if (!parent->close()) +			cout << "THIS SHOULD NEVER HAPPEN: tried to close, but event hasn't been accepted!" << endl; +	} +} +bool staff_t::cleanup_parts() +{ +	bool did_something=false; +	 +	for (set<Part*>::iterator it=parts.begin(); it!=parts.end();) +	{ +		bool valid=false; +		 +		for (iTrack track=song->tracks()->begin(); track!=song->tracks()->end(); track++) +			if ((*track)->type() == Track::MIDI) +			{ +				PartList* pl=(*track)->parts(); +				for (iPart part=pl->begin(); part!=pl->end(); part++) +					if (*it == part->second) +					{ +						valid=true; +						goto get_out_here2; +					} +			} +		 +		get_out_here2: +		if (!valid) +		{ +			parts.erase(it++); +			 +			did_something=true; +		} +		else +			it++; +	} +	 +	return did_something; +}  //the following assertions are made:  //  pix_quarter.width() == pix_half.width() @@ -3244,17 +3310,16 @@ void ScoreCanvas::set_quant(int val)   *   o automatically set x-raster (by quant. strength)   *    * IMPORTANT TODO - *   o removing the part the score's working on isn't handled   *   o let the user select the currently edited part   *   o support selections - *   o emit a "song-changed" signal instead of calling our - *     internal song_changed() function   *   o check if "moving away" works for whole notes [seems to NOT work properly] + * + * less important stuff   *   o more fine-grained redrawing in song_changed: sometimes,   *     only a redraw and not a recalc is needed   *   o do all the song_changed(SC_EVENT_INSERTED) properly - * - * less important stuff + *   o emit a "song-changed" signal instead of calling our + *     internal song_changed() function   *   o must add_parts() update the part-list?   *   o support different keys in different tracks at the same time   *       calc_pos_add_list and calc_item_pos will be affected by this @@ -3271,7 +3336,6 @@ void ScoreCanvas::set_quant(int val)   *     between, for example, when a cis is tied to a des   *   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 draw a margin around notes which are in a bright color   *   o maybe override color 0 with "black"? diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index c3ba246c..f512f7a0 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -438,11 +438,19 @@ struct staff_t  	ScoreCanvas* parent; -	void create_appropriate_eventlist(const set<Part*>& parts); +	void create_appropriate_eventlist();  	void create_itemlist();  	void process_itemlist();  	void calc_item_pos(); +	void recalculate() +	{ +		create_appropriate_eventlist(); +		create_itemlist(); +		process_itemlist(); +		calc_item_pos(); +	} +	  	staff_t(ScoreCanvas* parent_)  	{  		type=NORMAL; @@ -458,6 +466,8 @@ struct staff_t  		parts=parts_;  		parent=parent_;  	} +	 +	bool cleanup_parts();  };  list<int> calc_accidentials(key_enum key, clef_t clef, key_enum next_key=KEY_C); @@ -529,7 +539,8 @@ class ScoreCanvas : public View  		void set_staffmode(list<staff_t>::iterator it, staff_mode_t mode);  		void remove_staff(list<staff_t>::iterator it);  		void merge_staves(list<staff_t>::iterator dest, list<staff_t>::iterator src); -		 +		void cleanup_staves(); +		void maybe_close_if_empty();  // member variables ---------------------------------------------------  		int _quant_power2; @@ -632,7 +643,7 @@ class ScoreCanvas : public View  	protected:  		virtual void draw(QPainter& p, const QRect& rect); -		MidiEditor* editor; +		MidiEditor* parent;  		virtual void mousePressEvent (QMouseEvent* event);  		virtual void mouseMoveEvent (QMouseEvent* event); | 
