summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-05-11 12:38:56 +0000
committerFlorian Jung <flo@windfisch.org>2011-05-11 12:38:56 +0000
commite9c43888de8601c940b428c3bc6012f2ffe9f68c (patch)
tree20f4bd2fb4475acdb18cb2d522d8971bca6cef6d
parent8f13533997cb21f6cd1c523f888fd6f3e03cc22d (diff)
implemented erasing notes with [delete]
functions only indicate undo when something has really changed
-rw-r--r--muse2/muse/functions.cpp199
-rw-r--r--muse2/muse/functions.h1
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp21
-rw-r--r--muse2/muse/midiedit/scoreedit.h1
4 files changed, 130 insertions, 92 deletions
diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp
index 980a5103..6a3af374 100644
--- a/muse2/muse/functions.cpp
+++ b/muse2/muse/functions.cpp
@@ -54,6 +54,20 @@ bool is_relevant(const Event& event, const Part* part, int range)
}
}
+
+map<Event*, Part*> get_events(const set<Part*>& parts, int range)
+{
+ map<Event*, Part*> events;
+
+ for (set<Part*>::iterator part=parts.begin(); part!=parts.end(); part++)
+ for (iEvent event=(*part)->events()->begin(); event!=(*part)->events()->end(); event++)
+ if (is_relevant(event->second, *part, range))
+ events.insert(pair<Event*, Part*>(&event->second, *part));
+
+ return events;
+}
+
+
bool modify_notelen(const set<Part*>& parts)
{
if (!gatetime_dialog->exec())
@@ -89,78 +103,72 @@ bool quantize_notes(const set<Part*>& parts)
void modify_velocity(const set<Part*>& parts, int range, int rate, int offset)
{
- map<Event*, Part*> events;
-
- for (set<Part*>::iterator part=parts.begin(); part!=parts.end(); part++)
- for (iEvent event=(*part)->events()->begin(); event!=(*part)->events()->end(); event++)
- if (is_relevant(event->second, *part, range))
- events.insert(pair<Event*, Part*>(&event->second, *part));
-
-
- song->startUndo();
+ map<Event*, Part*> events = get_events(parts, range);
- for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++)
+ if (!events.empty())
{
- Event& event=*(it->first);
- Part* part=it->second;
+ song->startUndo();
- int velo = event.velo();
+ for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++)
+ {
+ Event& event=*(it->first);
+ Part* part=it->second;
+
+ int velo = event.velo();
- velo = (velo * rate) / 100;
- velo += offset;
+ velo = (velo * rate) / 100;
+ velo += offset;
- if (velo <= 0)
- velo = 1;
- else if (velo > 127)
- velo = 127;
-
- if (event.velo() != velo)
- {
- Event newEvent = event.clone();
- newEvent.setVelo(velo);
- // Indicate no undo, and do not do port controller values and clone parts.
- audio->msgChangeEvent(event, newEvent, part, false, false, false);
+ if (velo <= 0)
+ velo = 1;
+ else if (velo > 127)
+ velo = 127;
+
+ if (event.velo() != velo)
+ {
+ Event newEvent = event.clone();
+ newEvent.setVelo(velo);
+ // Indicate no undo, and do not do port controller values and clone parts.
+ audio->msgChangeEvent(event, newEvent, part, false, false, false);
+ }
}
+
+ song->endUndo(SC_EVENT_MODIFIED);
}
-
- song->endUndo(SC_EVENT_MODIFIED);
}
void modify_notelen(const set<Part*>& parts, int range, int rate, int offset)
{
- map<Event*, Part*> events;
-
- for (set<Part*>::iterator part=parts.begin(); part!=parts.end(); part++)
- for (iEvent event=(*part)->events()->begin(); event!=(*part)->events()->end(); event++)
- if (is_relevant(event->second, *part, range))
- events.insert(pair<Event*, Part*>(&event->second, *part));
+ map<Event*, Part*> events = get_events(parts, range);
-
- song->startUndo();
-
- for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++)
+ if (!events.empty())
{
- Event& event=*(it->first);
- Part* part=it->second;
+ song->startUndo();
+
+ for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++)
+ {
+ Event& event=*(it->first);
+ Part* part=it->second;
- unsigned int len = event.lenTick(); //prevent compiler warning: comparison singed/unsigned
+ unsigned int len = event.lenTick(); //prevent compiler warning: comparison singed/unsigned
- len = (len * rate) / 100;
- len += offset;
+ len = (len * rate) / 100;
+ len += offset;
- if (len <= 0)
- len = 1;
-
- if (event.lenTick() != len)
- {
- Event newEvent = event.clone();
- newEvent.setLenTick(len);
- // Indicate no undo, and do not do port controller values and clone parts.
- audio->msgChangeEvent(event, newEvent, part, false, false, false);
+ if (len <= 0)
+ len = 1;
+
+ if (event.lenTick() != len)
+ {
+ Event newEvent = event.clone();
+ newEvent.setLenTick(len);
+ // Indicate no undo, and do not do port controller values and clone parts.
+ audio->msgChangeEvent(event, newEvent, part, false, false, false);
+ }
}
+
+ song->endUndo(SC_EVENT_MODIFIED);
}
-
- song->endUndo(SC_EVENT_MODIFIED);
}
unsigned quantize_tick(unsigned tick, unsigned raster, int swing)
@@ -187,51 +195,68 @@ unsigned quantize_tick(unsigned tick, unsigned raster, int swing)
void quantize_notes(const set<Part*>& parts, int range, int raster, int strength, int swing, int threshold)
{
- map<Event*, Part*> events;
-
- for (set<Part*>::iterator part=parts.begin(); part!=parts.end(); part++)
- for (iEvent event=(*part)->events()->begin(); event!=(*part)->events()->end(); event++)
- if (is_relevant(event->second, *part, range))
- events.insert(pair<Event*, Part*>(&event->second, *part));
-
-
- song->startUndo();
+ map<Event*, Part*> events = get_events(parts, range);
- for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++)
+ if (!events.empty())
{
- Event& event=*(it->first);
- Part* part=it->second;
+ song->startUndo();
+
+ for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++)
+ {
+ Event& event=*(it->first);
+ Part* part=it->second;
- unsigned begin_tick = event.tick() + part->tick();
- int begin_diff = quantize_tick(begin_tick, raster, swing) - begin_tick;
+ unsigned begin_tick = event.tick() + part->tick();
+ int begin_diff = quantize_tick(begin_tick, raster, swing) - begin_tick;
- if (abs(begin_diff) > threshold)
- begin_tick = begin_tick + begin_diff*strength/100;
+ if (abs(begin_diff) > threshold)
+ begin_tick = begin_tick + begin_diff*strength/100;
- unsigned len=event.lenTick();
-
- unsigned end_tick = begin_tick + len;
- int len_diff = quantize_tick(end_tick, raster, swing) - end_tick;
+ unsigned len=event.lenTick();
- if (abs(len_diff) > threshold)
- len = len + len_diff*strength/100;
+ unsigned end_tick = begin_tick + len;
+ int len_diff = quantize_tick(end_tick, raster, swing) - end_tick;
+
+ if (abs(len_diff) > threshold)
+ len = len + len_diff*strength/100;
- if (len <= 0)
- len = 1;
+ if (len <= 0)
+ len = 1;
-
- if ( (event.lenTick() != len) || (event.tick() + part->tick() != begin_tick) )
- {
- Event newEvent = event.clone();
- newEvent.setTick(begin_tick - part->tick());
- newEvent.setLenTick(len);
- // Indicate no undo, and do not do port controller values and clone parts.
- audio->msgChangeEvent(event, newEvent, part, false, false, false);
+
+ if ( (event.lenTick() != len) || (event.tick() + part->tick() != begin_tick) )
+ {
+ Event newEvent = event.clone();
+ newEvent.setTick(begin_tick - part->tick());
+ newEvent.setLenTick(len);
+ // Indicate no undo, and do not do port controller values and clone parts.
+ audio->msgChangeEvent(event, newEvent, part, false, false, false);
+ }
}
+
+ song->endUndo(SC_EVENT_MODIFIED);
}
+}
+
+void erase_notes(const set<Part*>& parts, int range)
+{
+ map<Event*, Part*> events = get_events(parts, range);
- song->endUndo(SC_EVENT_MODIFIED);
+ if (!events.empty())
+ {
+ song->startUndo();
+
+ for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++)
+ {
+ Event& event=*(it->first);
+ Part* part=it->second;
+
+ audio->msgDeleteEvent(event, part, false, false, false);
+ }
+
+ song->endUndo(SC_EVENT_REMOVED);
+ }
}
diff --git a/muse2/muse/functions.h b/muse2/muse/functions.h
index a71230a4..03d0ba88 100644
--- a/muse2/muse/functions.h
+++ b/muse2/muse/functions.h
@@ -29,6 +29,7 @@ std::set<Part*> partlist_to_set(PartList* pl);
void modify_velocity(const std::set<Part*>& parts, int range, int rate, int offset=0);
void modify_notelen(const std::set<Part*>& parts, int range, int rate, int offset=0);
void quantize_notes(const std::set<Part*>& parts, int range, int raster, int strength=100, int swing=0, int threshold=0);
+void erase_notes(const std::set<Part*>& parts, int range);
//the below functions automatically open the dialog
//they return true if you click "ok" and false if "abort"
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index 4471f48e..02151227 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -3451,6 +3451,8 @@ void ScoreCanvas::mouseReleaseEvent (QMouseEvent* event)
for (list<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++)
it->apply_lasso(lasso.translated(x_pos-x_left, y_pos - it->y_draw), already_processed);
+ song->update(SC_SELECTION);
+
have_lasso=false;
redraw();
}
@@ -3937,7 +3939,15 @@ void ScoreCanvas::deselect_all()
for (iEvent event=(*part)->events()->begin(); event!=(*part)->events()->end(); event++)
event->second.setSelected(false);
- song_changed(SC_SELECTION);
+ song->update(SC_SELECTION);
+}
+
+void ScoreCanvas::keyPressEvent(QKeyEvent* event)
+{
+ if (event->key()==Qt::Key_Delete)
+ {
+ erase_notes(get_all_parts(), 1); // 1 means "all selected"
+ }
}
bool staff_t::cleanup_parts()
@@ -4027,12 +4037,9 @@ void staff_t::apply_lasso(QRect rect, set<Event*>& already_processed)
* between, for example, when a cis is tied to a des
*
* CURRENT TODO
- * o use "DEL" for deleting all selected items
* o let the user select the distance between staves, or do this
* automatically?
- * o update translations
- * o remove ambiguous translation: "offset"="zeitversatz"
- * this is ambigous in mod. note len and WRONG in mod. velo dialogs
+ * o don't indicate undo when only clicking on an item
*
* IMPORTANT TODO
* o add a select-clef-toolbox for tracks
@@ -4065,6 +4072,10 @@ void staff_t::apply_lasso(QRect rect, set<Event*>& already_processed)
*
*
* stuff for the other muse developers
+ * o update translations
+ * o remove ambiguous translation: "offset"="zeitversatz"
+ * this is ambigous in mod. note len and WRONG in mod. velo dialogs
+
* 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 )
* o maybe do expanding parts inside the msgChangeEvent or
diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h
index 74bc0283..e46f408a 100644
--- a/muse2/muse/midiedit/scoreedit.h
+++ b/muse2/muse/midiedit/scoreedit.h
@@ -715,6 +715,7 @@ class ScoreCanvas : public View
virtual void mouseMoveEvent (QMouseEvent* event);
virtual void mouseReleaseEvent (QMouseEvent* event);
virtual void resizeEvent(QResizeEvent*);
+ virtual void keyPressEvent(QKeyEvent* event);
public:
ScoreCanvas(ScoreEdit*, QWidget*, int, int);