summaryrefslogtreecommitdiff
path: root/muse2/muse
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-04-21 18:46:48 +0000
committerFlorian Jung <flo@windfisch.org>2011-04-21 18:46:48 +0000
commite544d366103630a39d72998bcef2e4970d0d0ea1 (patch)
tree43cfe3f36ab7180f92943e74d9623791d9a15f0a /muse2/muse
parentba3b8723b9672bd42888da2e9f1f644393a46c39 (diff)
removing a currently shown part is now handled gracefully
the score window automatically closes if the last staff is removed
Diffstat (limited to 'muse2/muse')
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp106
-rw-r--r--muse2/muse/midiedit/scoreedit.h17
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);