make shift-click for extend-selection sort-of work for MIDI
git-svn-id: svn://localhost/ardour2/branches/3.0@5541 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
3162ffb4f4
commit
b116282bbb
@ -325,22 +325,21 @@ CanvasNoteEvent::on_event(GdkEvent* ev)
|
||||
case Pressed: // Clicked
|
||||
if (editor.current_mouse_mode() == Editing::MouseRange) {
|
||||
_state = None;
|
||||
if (_selected && !select_mod && _region.selection_size() > 1) {
|
||||
_region.unique_select(this);
|
||||
} else if (_selected) {
|
||||
if (_selected) {
|
||||
_region.note_deselected(this, select_mod);
|
||||
} else {
|
||||
_region.note_selected(this, select_mod);
|
||||
}
|
||||
#if 0
|
||||
} else if (midi_edit_mode == Editing::MidiEditErase) {
|
||||
_region.start_delta_command();
|
||||
_region.command_remove_note(this);
|
||||
_region.apply_command();
|
||||
#endif
|
||||
}
|
||||
bool extend = Keyboard::modifier_state_equals (ev->motion.state, Keyboard::TertiaryModifier);
|
||||
bool add = Keyboard::modifier_state_equals (ev->motion.state, Keyboard::PrimaryModifier);
|
||||
|
||||
if (!extend && !add && _region.selection_size() > 1) {
|
||||
_region.unique_select(this);
|
||||
} else {
|
||||
_region.note_selected (this, (extend ? true : add), extend);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
case Dragging: // Dropped
|
||||
_item->ungrab(ev->button.time);
|
||||
_state = None;
|
||||
|
@ -331,6 +331,8 @@ class Editor : public PublicEditor
|
||||
|
||||
/* nudge is initiated by transport controls owned by ARDOUR_UI */
|
||||
|
||||
nframes64_t get_nudge_distance (nframes64_t pos, nframes64_t& next);
|
||||
|
||||
void nudge_forward (bool next, bool force_playhead);
|
||||
void nudge_backward (bool next, bool force_playhead);
|
||||
|
||||
@ -1901,8 +1903,6 @@ public:
|
||||
Gtk::VBox nudge_vbox;
|
||||
AudioClock nudge_clock;
|
||||
|
||||
nframes64_t get_nudge_distance (nframes64_t pos, nframes64_t& next);
|
||||
|
||||
bool nudge_forward_release (GdkEventButton*);
|
||||
bool nudge_backward_release (GdkEventButton*);
|
||||
|
||||
|
@ -214,6 +214,10 @@ MidiRegionView::canvas_event(GdkEvent* ev)
|
||||
|
||||
static ArdourCanvas::SimpleRect* drag_rect = NULL;
|
||||
|
||||
/* XXX: note that as of August 2009, the GnomeCanvas does not propagate scroll events
|
||||
to its items, which means that ev->type == GDK_SCROLL will never be seen
|
||||
*/
|
||||
|
||||
switch (ev->type) {
|
||||
case GDK_SCROLL:
|
||||
if (Keyboard::modifier_state_equals (ev->scroll.state, Keyboard::Level4Modifier)) {
|
||||
@ -273,11 +277,11 @@ MidiRegionView::canvas_event(GdkEvent* ev)
|
||||
}
|
||||
} else if (ev->key.keyval == GDK_Left) {
|
||||
|
||||
nudge_notes (-1.0);
|
||||
nudge_notes (false);
|
||||
|
||||
} else if (ev->key.keyval == GDK_Right) {
|
||||
|
||||
nudge_notes (1.0);
|
||||
nudge_notes (true);
|
||||
|
||||
}
|
||||
return false;
|
||||
@ -1233,14 +1237,49 @@ MidiRegionView::unique_select(ArdourCanvas::CanvasNoteEvent* ev)
|
||||
}
|
||||
|
||||
void
|
||||
MidiRegionView::note_selected(ArdourCanvas::CanvasNoteEvent* ev, bool add)
|
||||
MidiRegionView::note_selected(ArdourCanvas::CanvasNoteEvent* ev, bool add, bool extend)
|
||||
{
|
||||
if (!add) {
|
||||
clear_selection_except(ev);
|
||||
}
|
||||
|
||||
if (!ev->selected()) {
|
||||
add_to_selection (ev);
|
||||
if (!extend) {
|
||||
|
||||
if (!ev->selected()) {
|
||||
add_to_selection (ev);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* find end of latest note selected, select all between that and the start of "ev" */
|
||||
|
||||
MidiModel::TimeType earliest = DBL_MAX;
|
||||
MidiModel::TimeType latest = 0;
|
||||
|
||||
for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
|
||||
if ((*i)->note()->end_time() > latest) {
|
||||
latest = (*i)->note()->end_time();
|
||||
}
|
||||
if ((*i)->note()->time() < earliest) {
|
||||
earliest = (*i)->note()->time();
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->note()->end_time() > latest) {
|
||||
earliest = latest;
|
||||
latest = ev->note()->end_time();
|
||||
} else {
|
||||
earliest = ev->note()->time();
|
||||
}
|
||||
|
||||
for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
if ((*i)->note()->time() >= earliest && (*i)->note()->end_time() <= latest) {
|
||||
add_to_selection (*i);
|
||||
}
|
||||
|
||||
if ((*i)->note()->end_time() > latest) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1654,29 +1693,13 @@ MidiRegionView::change_note_time (CanvasNoteEvent* event, MidiModel::TimeType de
|
||||
command_add_note(copy, event->selected(), false);
|
||||
}
|
||||
|
||||
void
|
||||
MidiRegionView::change_velocity(CanvasNoteEvent* ev, int8_t velocity, bool relative)
|
||||
{
|
||||
start_delta_command(_("change velocity"));
|
||||
|
||||
change_note_velocity(ev, velocity, relative);
|
||||
|
||||
for (Selection::iterator i = _selection.begin(); i != _selection.end();) {
|
||||
Selection::iterator next = i;
|
||||
++next;
|
||||
if ( !(*((*i)->note()) == *(ev->note())) ) {
|
||||
change_note_velocity(*i, velocity, relative);
|
||||
}
|
||||
i = next;
|
||||
}
|
||||
|
||||
apply_command();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MidiRegionView::change_velocities (int8_t velocity, bool relative)
|
||||
{
|
||||
if (_selection.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
start_delta_command(_("change velocities"));
|
||||
|
||||
for (Selection::iterator i = _selection.begin(); i != _selection.end();) {
|
||||
@ -1693,6 +1716,10 @@ MidiRegionView::change_velocities (int8_t velocity, bool relative)
|
||||
void
|
||||
MidiRegionView::transpose (bool up, bool fine)
|
||||
{
|
||||
if (_selection.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int8_t delta;
|
||||
|
||||
if (fine) {
|
||||
@ -1718,8 +1745,40 @@ MidiRegionView::transpose (bool up, bool fine)
|
||||
}
|
||||
|
||||
void
|
||||
MidiRegionView::nudge_notes (MidiModel::TimeType delta)
|
||||
MidiRegionView::nudge_notes (bool forward)
|
||||
{
|
||||
if (_selection.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* pick a note as the point along the timeline to get the nudge distance.
|
||||
its not necessarily the earliest note, so we may want to pull the notes out
|
||||
into a vector and sort before using the first one.
|
||||
*/
|
||||
|
||||
nframes64_t ref_point = _region->position() + beats_to_frames ((*(_selection.begin()))->note()->time());
|
||||
nframes64_t next_pos = ref_point;
|
||||
|
||||
if (forward) {
|
||||
next_pos += 1;
|
||||
} else {
|
||||
if (next_pos == 0) {
|
||||
return;
|
||||
}
|
||||
next_pos -= 1;
|
||||
}
|
||||
|
||||
trackview.editor().snap_to (next_pos, (forward ? 1 : -1), false);
|
||||
nframes64_t distance = ref_point - next_pos;
|
||||
|
||||
cerr << "ref was " << ref_point << " next is " << next_pos << endl;
|
||||
|
||||
MidiModel::TimeType delta = frames_to_beats (fabs (distance));
|
||||
|
||||
if (!forward) {
|
||||
delta = -delta;
|
||||
}
|
||||
|
||||
start_delta_command (_("nudge"));
|
||||
|
||||
for (Selection::iterator i = _selection.begin(); i != _selection.end(); ) {
|
||||
@ -1897,7 +1956,6 @@ MidiRegionView::paste (nframes64_t pos, float times, const MidiCutBuffer& mcb)
|
||||
copied_note->set_time (paste_pos_beats + copied_note->time() - beat_delta);
|
||||
|
||||
/* make all newly added notes selected */
|
||||
cerr << "\tadd @ " << copied_note->time() << endl;
|
||||
|
||||
command_add_note (copied_note, true);
|
||||
end_point = copied_note->end_time();
|
||||
@ -1911,15 +1969,12 @@ MidiRegionView::paste (nframes64_t pos, float times, const MidiCutBuffer& mcb)
|
||||
nframes64_t end_frame = _region->position() + beats_to_frames (end_point);
|
||||
nframes64_t region_end = _region->position() + _region->length() - 1;
|
||||
|
||||
cerr << "\tEnd frame = " << end_frame << " from " << end_point << " region end = " << region_end << endl;
|
||||
|
||||
if (end_frame > region_end) {
|
||||
|
||||
trackview.session().begin_reversible_command (_("paste"));
|
||||
|
||||
XMLNode& before (_region->get_state());
|
||||
_region->set_length (end_frame, this);
|
||||
cerr << "\textended to " << end_frame << endl;
|
||||
trackview.session().add_command (new MementoCommand<Region>(*_region, &before, &_region->get_state()));
|
||||
}
|
||||
|
||||
@ -1929,30 +1984,52 @@ MidiRegionView::paste (nframes64_t pos, float times, const MidiCutBuffer& mcb)
|
||||
void
|
||||
MidiRegionView::goto_next_note ()
|
||||
{
|
||||
nframes64_t pos = trackview.session().transport_frame();
|
||||
// nframes64_t pos = -1;
|
||||
bool use_next = false;
|
||||
|
||||
if (_events.back()->selected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
nframes64_t npos = _region->position() + beats_to_frames ((*i)->note()->time());
|
||||
|
||||
if (npos >= pos && !(*i)->selected()) {
|
||||
if ((*i)->selected()) {
|
||||
use_next = true;
|
||||
continue;
|
||||
} else if (use_next) {
|
||||
unique_select (*i);
|
||||
trackview.session().request_locate (npos);
|
||||
// pos = _region->position() + beats_to_frames ((*i)->note()->time());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* use the first one */
|
||||
|
||||
unique_select (_events.front());
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MidiRegionView::goto_previous_note ()
|
||||
{
|
||||
nframes64_t pos = trackview.session().transport_frame();
|
||||
// nframes64_t pos = -1;
|
||||
bool use_next = false;
|
||||
|
||||
if (_events.front()->selected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Events::reverse_iterator i = _events.rbegin(); i != _events.rend(); ++i) {
|
||||
nframes64_t npos = _region->position() + beats_to_frames ((*i)->note()->time());
|
||||
if (npos <= pos && !(*i)->selected()) {
|
||||
if ((*i)->selected()) {
|
||||
use_next = true;
|
||||
continue;
|
||||
} else if (use_next) {
|
||||
unique_select (*i);
|
||||
trackview.session().request_locate (npos);
|
||||
// pos = _region->position() + beats_to_frames ((*i)->note()->time());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* use the last one */
|
||||
|
||||
unique_select (*(_events.rbegin()));
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ class MidiRegionView : public RegionView
|
||||
|
||||
void note_entered(ArdourCanvas::CanvasNoteEvent* ev);
|
||||
void unique_select(ArdourCanvas::CanvasNoteEvent* ev);
|
||||
void note_selected(ArdourCanvas::CanvasNoteEvent* ev, bool add);
|
||||
void note_selected(ArdourCanvas::CanvasNoteEvent* ev, bool add, bool extend=false);
|
||||
void note_deselected(ArdourCanvas::CanvasNoteEvent* ev, bool add);
|
||||
void delete_selection();
|
||||
size_t selection_size() { return _selection.size(); }
|
||||
@ -265,7 +265,7 @@ class MidiRegionView : public RegionView
|
||||
void goto_next_note ();
|
||||
void change_velocities (int8_t velocity, bool relative);
|
||||
void transpose (bool up, bool fine);
|
||||
void nudge_notes (ARDOUR::MidiModel::TimeType delta);
|
||||
void nudge_notes (bool forward);
|
||||
|
||||
protected:
|
||||
/** Allows derived types to specify their visibility requirements
|
||||
|
@ -263,6 +263,8 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
|
||||
virtual void mouse_add_new_marker (nframes64_t where, bool is_cd=false, bool is_xrun=false) = 0;
|
||||
virtual void foreach_time_axis_view (sigc::slot<void,TimeAxisView&>) = 0;
|
||||
virtual void add_to_idle_resize (TimeAxisView*, int32_t) = 0;
|
||||
virtual nframes64_t get_nudge_distance (nframes64_t pos, nframes64_t& next) = 0;
|
||||
|
||||
|
||||
#ifdef WITH_CMT
|
||||
virtual void add_imageframe_time_axis(const std::string & track_name, void*) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user