X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fmidi_region_view.cc;h=b12f8ef4d90b19e4525f962282f376ab10afab1c;hb=e486a8d86fee39b3bcca59441eb5d1c945cbef19;hp=dfcd630d163966a6a0ac73b68c7550cd2e9dcdec;hpb=e14ab95dc533ffb806f97b46fd523943763feb62;p=ardour.git diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index dfcd630d16..b12f8ef4d9 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -45,6 +45,8 @@ #include "public_editor.h" #include "ghostregion.h" #include "midi_time_axis.h" +#include "automation_time_axis.h" +#include "automation_region_view.h" #include "utils.h" #include "midi_util.h" #include "gui_thread.h" @@ -58,8 +60,7 @@ using namespace PBD; using namespace Editing; using namespace ArdourCanvas; -MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr r, double spu, - Gdk::Color& basic_color) +MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr r, double spu, Gdk::Color& basic_color) : RegionView (parent, tv, r, spu, basic_color) , _default_note_length(0.0) , _active_notes(0) @@ -71,8 +72,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & _note_group->raise_to_top(); } -MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr r, double spu, - Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility) +MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr r, double spu, Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility) : RegionView (parent, tv, r, spu, basic_color, visibility) , _default_note_length(0.0) , _active_notes(0) @@ -122,6 +122,8 @@ MidiRegionView::init (Gdk::Color& basic_color, bool wfd) } _model->ContentsChanged.connect(sigc::mem_fun(this, &MidiRegionView::redisplay_model)); } + + midi_region()->midi_source(0)->Switched.connect(sigc::mem_fun(this, &MidiRegionView::switch_source)); group->signal_event().connect (mem_fun (this, &MidiRegionView::canvas_event), false); @@ -147,20 +149,20 @@ MidiRegionView::canvas_event(GdkEvent* ev) switch (ev->type) { case GDK_KEY_PRESS: - cerr << "REGION KEY PRESS\n"; if (ev->key.keyval == GDK_Delete && !delete_mod) { delete_mod = true; original_mode = trackview.editor.current_midi_edit_mode(); trackview.editor.set_midi_edit_mode(MidiEditErase); start_remove_command(); - _mouse_state = EraseDragging; + _mouse_state = EraseTouchDragging; + } else if (ev->key.keyval == GDK_Shift_L || ev->key.keyval == GDK_Control_L) { + _mouse_state = SelectTouchDragging; } return true; case GDK_KEY_RELEASE: - cerr << "REGION KEY RELEASE\n"; if (ev->key.keyval == GDK_Delete) { - if (_mouse_state == EraseDragging) { + if (_mouse_state == EraseTouchDragging) { delete_selection(); apply_command(); } @@ -168,14 +170,15 @@ MidiRegionView::canvas_event(GdkEvent* ev) trackview.editor.set_midi_edit_mode(original_mode); delete_mod = false; } + } else if (ev->key.keyval == GDK_Shift_L || ev->key.keyval == GDK_Control_L) { + _mouse_state = None; } return true; case GDK_BUTTON_PRESS: - //group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, ev->button.time); - _mouse_state = Pressed; + if (_mouse_state != SelectTouchDragging && _mouse_state != EraseTouchDragging) + _mouse_state = Pressed; _pressed_button = ev->button.button; - //cerr << "PRESSED: " << press_button << endl; return true; case GDK_ENTER_NOTIFY: @@ -197,7 +200,6 @@ MidiRegionView::canvas_event(GdkEvent* ev) // Select drag start if (_pressed_button == 1 && trackview.editor.current_midi_edit_mode() == MidiEditSelect) { - cerr << "SELECT START\n"; group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, Gdk::Cursor(Gdk::FLEUR), ev->motion.time); last_x = event_x; @@ -216,12 +218,11 @@ MidiRegionView::canvas_event(GdkEvent* ev) drag_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiSelectRectFill.get(); - _mouse_state = SelectDragging; + _mouse_state = SelectRectDragging; return true; // Add note drag start } else if (trackview.editor.current_midi_edit_mode() == MidiEditPencil) { - cerr << "PENCIL START\n"; group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, Gdk::Cursor(Gdk::FLEUR), ev->motion.time); last_x = event_x; @@ -242,17 +243,11 @@ MidiRegionView::canvas_event(GdkEvent* ev) _mouse_state = AddDragging; return true; - - // Eraser drag start - } else if (trackview.editor.current_midi_edit_mode() == MidiEditErase) { - cerr << "ERASE DRAGGING\n"; - _mouse_state = EraseDragging; - return false; // ? } - break; + return false; - case SelectDragging: // Select drag motion + case SelectRectDragging: // Select drag motion case AddDragging: // Add note drag motion if (ev->motion.is_hint) { int t_x; @@ -272,7 +267,7 @@ MidiRegionView::canvas_event(GdkEvent* ev) else drag_rect->property_x1() = event_x; - if (drag_rect && _mouse_state == SelectDragging) { + if (drag_rect && _mouse_state == SelectRectDragging) { if (event_y > drag_start_y) drag_rect->property_y2() = event_y; else @@ -284,11 +279,11 @@ MidiRegionView::canvas_event(GdkEvent* ev) last_x = event_x; last_y = event_y; - case EraseDragging: - return true; + case EraseTouchDragging: + case SelectTouchDragging: + return false; default: - _mouse_state = None; break; } break; @@ -315,7 +310,7 @@ MidiRegionView::canvas_event(GdkEvent* ev) } _mouse_state = None; return true; - case SelectDragging: // Select drag done + case SelectRectDragging: // Select drag done _mouse_state = None; delete drag_rect; drag_rect = NULL; @@ -399,17 +394,54 @@ MidiRegionView::display_model(boost::shared_ptr model) void MidiRegionView::redisplay_model() { - clear_events(); + // Don't redisplay the model if we're currently recording and displaying that + if (_active_notes) + return; if (_model) { + + clear_events(); begin_write(); + + _model->read_lock(); for (size_t i=0; i < _model->n_notes(); ++i) add_note(_model->note_at(i)); end_write(); + + for (Automatable::Controls::const_iterator i = _model->controls().begin(); + i != _model->controls().end(); ++i) { + + assert(i->second); + + boost::shared_ptr at + = midi_view()->automation_child(i->second->parameter()); + if (!at) + continue; + + Gdk::Color col = midi_stream_view()->get_region_color(); + + boost::shared_ptr arv; + + { + Glib::Mutex::Lock list_lock (i->second->list()->lock()); + + arv = boost::shared_ptr( + new AutomationRegionView(at->canvas_display, + *at.get(), _region, i->second->list(), + midi_stream_view()->get_samples_per_unit(), col)); + + _automation_children.insert(std::make_pair(i->second->parameter(), arv)); + } + + arv->init(col, true); + } + + _model->read_unlock(); + } else { - warning << "MidiRegionView::redisplay_model called without a model" << endmsg; + cerr << "MidiRegionView::redisplay_model called without a model" << endmsg; } } @@ -417,7 +449,10 @@ MidiRegionView::redisplay_model() MidiRegionView::~MidiRegionView () { in_destructor = true; - end_write(); + if (_active_notes) + end_write(); + + clear_events(); RegionViewGoingAway (this); /* EMIT_SIGNAL */ } @@ -491,6 +526,7 @@ MidiRegionView::add_ghost (AutomationTimeAxisView& atv) void MidiRegionView::begin_write() { + assert(!_active_notes); _active_notes = new CanvasNote*[128]; for (unsigned i=0; i < 128; ++i) _active_notes[i] = NULL; @@ -515,9 +551,9 @@ MidiRegionView::end_write() void MidiRegionView::add_event (const MidiEvent& ev) { - /*printf("Event, time = %f, size = %zu, data = ", ev.time, ev.size); - for (size_t i=0; i < ev.size; ++i) { - printf("%X ", ev.buffer[i]); + /*printf("MRV add Event, time = %f, size = %u, data = ", ev.time(), ev.size()); + for (size_t i=0; i < ev.size(); ++i) { + printf("%X ", ev.buffer()[i]); } printf("\n\n");*/ @@ -661,7 +697,9 @@ MidiRegionView::unique_select(ArdourCanvas::CanvasMidiEvent* ev) _selection.clear(); _selection.insert(ev); - ev->selected(true); + + if ( ! ev->selected()) + ev->selected(true); } void @@ -671,7 +709,9 @@ MidiRegionView::note_selected(ArdourCanvas::CanvasMidiEvent* ev, bool add) clear_selection_except(ev); _selection.insert(ev); - ev->selected(true); + + if ( ! ev->selected()) + ev->selected(true); } @@ -682,7 +722,9 @@ MidiRegionView::note_deselected(ArdourCanvas::CanvasMidiEvent* ev, bool add) clear_selection_except(ev); _selection.erase(ev); - ev->selected(false); + + if (ev->selected()) + ev->selected(false); } @@ -725,6 +767,7 @@ MidiRegionView::move_selection(double dx, double dy) (*i)->item()->move(dx, dy); } + void MidiRegionView::note_dropped(CanvasMidiEvent* ev, double dt, uint8_t dnote) { @@ -744,4 +787,27 @@ MidiRegionView::note_dropped(CanvasMidiEvent* ev, double dt, uint8_t dnote) apply_command(); } } + + +void +MidiRegionView::note_entered(ArdourCanvas::CanvasMidiEvent* ev) +{ + cerr << "NOTE ENTERED: " << _mouse_state << endl; + if (ev->note() && _mouse_state == EraseTouchDragging) { + start_delta_command(); + ev->selected(true); + _delta_command->remove(*ev->note()); + } else if (_mouse_state == SelectTouchDragging) { + note_selected(ev, true); + } +} + + +void +MidiRegionView::switch_source(boost::shared_ptr src) +{ + boost::shared_ptr msrc = boost::dynamic_pointer_cast(src); + if (msrc) + display_model(msrc->model()); +}