X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fmidi_region_view.cc;h=ac982a3040146771de7a4e9030031230160e5215;hb=ba8953605dd8359f0ec8a2aacb51102deda05df7;hp=ca9cd4af717241a136df9a9167f618ad48b4cb71;hpb=960de7306f8573f6cb698cf031fad46daa3c741d;p=ardour.git diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index ca9cd4af71..ac982a3040 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -48,6 +48,7 @@ #include "canvas-hit.h" #include "canvas-note.h" #include "canvas_patch_change.h" +#include "canvas-sysex.h" #include "debug.h" #include "editor.h" #include "editor_drag.h" @@ -115,6 +116,13 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & _note_group->raise_to_top(); PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys)); + + MidiTimeAxisView *time_axis = dynamic_cast(&tv); + if (time_axis) { + _last_channel_mode = time_axis->channel_selector().get_channel_mode(); + _last_channel_selection = time_axis->channel_selector().get_selected_channels(); + } + Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&MidiRegionView::parameter_changed, this, _1), gui_context()); connect_to_diskstream (); @@ -152,6 +160,12 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & _note_group->raise_to_top(); PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys)); + MidiTimeAxisView *time_axis = dynamic_cast(&tv); + if (time_axis) { + _last_channel_mode = time_axis->channel_selector().get_channel_mode(); + _last_channel_selection = time_axis->channel_selector().get_selected_channels(); + } + connect_to_diskstream (); SelectionCleared.connect (_selection_cleared_connection, invalidator (*this), boost::bind (&MidiRegionView::selection_cleared, this, _1), gui_context ()); @@ -265,8 +279,6 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd) region_resized (ARDOUR::bounds_change); region_locked (); - reset_width_dependent_items (_pixel_width); - set_colors (); _enable_display = true; @@ -276,18 +288,16 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd) } } + reset_width_dependent_items (_pixel_width); + group->raise_to_top(); - group->signal_event().connect( - sigc::mem_fun(this, &MidiRegionView::canvas_event), false); + group->signal_event().connect (sigc::mem_fun (this, &MidiRegionView::canvas_event), false); midi_view()->signal_channel_mode_changed().connect( sigc::mem_fun(this, &MidiRegionView::midi_channel_mode_changed)); - RouteUI* route_ui = dynamic_cast (&trackview); - if (route_ui) { - route_ui->route()->instrument_info().Changed.connect (_instrument_changed_connection, invalidator (*this), - boost::bind (&MidiRegionView::instrument_settings_changed, this), gui_context()); - } + instrument_info().Changed.connect (_instrument_changed_connection, invalidator (*this), + boost::bind (&MidiRegionView::instrument_settings_changed, this), gui_context()); trackview.editor().SnapChanged.connect(snap_changed_connection, invalidator(*this), boost::bind (&MidiRegionView::snap_changed, this), @@ -299,6 +309,13 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd) SelectionCleared.connect (_selection_cleared_connection, invalidator (*this), boost::bind (&MidiRegionView::selection_cleared, this, _1), gui_context ()); } +InstrumentInfo& +MidiRegionView::instrument_info () const +{ + RouteUI* route_ui = dynamic_cast (&trackview); + return route_ui->route()->instrument_info(); +} + const boost::shared_ptr MidiRegionView::midi_region() const { @@ -318,7 +335,7 @@ bool MidiRegionView::canvas_event(GdkEvent* ev) { bool r; - + switch (ev->type) { case GDK_ENTER_NOTIFY: case GDK_LEAVE_NOTIFY: @@ -334,7 +351,12 @@ MidiRegionView::canvas_event(GdkEvent* ev) } if (ev->type == GDK_2BUTTON_PRESS) { - return trackview.editor().toggle_internal_editing_from_double_click (ev); + // cannot use double-click to exit internal mode if single-click is being used + MouseMode m = trackview.editor().current_mouse_mode(); + + if ((m != MouseObject || !Keyboard::modifier_state_contains (ev->button.state, Keyboard::insert_note_modifier())) && (m != MouseDraw)) { + return trackview.editor().toggle_internal_editing_from_double_click (ev); + } } if ((!trackview.editor().internal_editing() && trackview.editor().current_mouse_mode() != MouseGain) || @@ -677,7 +699,11 @@ MidiRegionView::scroll (GdkEventScroll* ev) change_velocities (true, fine, false, together); } else if (ev->direction == GDK_SCROLL_DOWN) { change_velocities (false, fine, false, together); + } else { + /* left, right: we don't use them */ + return false; } + return true; } @@ -710,7 +736,11 @@ MidiRegionView::key_press (GdkEventKey* ev) return true; - } else if (ev->keyval == GDK_Delete && unmodified) { + } else if ((ev->keyval == GDK_BackSpace || ev->keyval == GDK_Delete) && unmodified) { + + if (_selection.empty()) { + return false; + } delete_selection(); return true; @@ -921,9 +951,9 @@ MidiRegionView::create_note_at (framepos_t t, double y, double length, bool snap } void -MidiRegionView::clear_events() +MidiRegionView::clear_events (bool with_selection_signal) { - clear_selection(); + clear_selection (with_selection_signal); MidiGhostRegion* gr; for (std::vector::iterator g = ghosts.begin(); g != ghosts.end(); ++g) { @@ -1204,10 +1234,8 @@ MidiRegionView::display_patch_changes_on_channel (uint8_t channel, bool active_c continue; } - // MidiTimeAxisView* const mtv = dynamic_cast(&trackview); - //string patch_name = mtv->get_patch_name ((*i)->bank(), (*i)->program(), channel); - - // add_canvas_patch_change (*i, patch_name, active_channel); + string patch_name = instrument_info().get_patch_name ((*i)->bank(), (*i)->program(), channel); + add_canvas_patch_change (*i, patch_name, active_channel); } } @@ -1277,12 +1305,12 @@ MidiRegionView::display_sysexes() } string text = str.str(); - const double x = trackview.editor().frame_to_pixel(source_beats_to_absolute_frames(time)); + const double x = trackview.editor().frame_to_pixel(source_beats_to_region_frames(time)); double height = midi_stream_view()->contents_height(); boost::shared_ptr sysex = boost::shared_ptr( - new CanvasSysEx(*this, *_note_group, text, height, x, 1.0)); + new CanvasSysEx(*this, *_note_group, text, height, x, 1.0, (*i))); // Show unless message is beyond the region bounds if (time - _region->start() >= _region->length() || time < _region->start()) { @@ -1314,7 +1342,7 @@ MidiRegionView::~MidiRegionView () _selection_cleared_connection.disconnect (); _selection.clear(); - clear_events(); + clear_events (false); delete _note_group; delete _note_diff_command; @@ -1345,6 +1373,14 @@ MidiRegionView::reset_width_dependent_items (double pixel_width) redisplay_model(); } + for (PatchChanges::iterator x = _patch_changes.begin(); x != _patch_changes.end(); ++x) { + if ((*x)->width() >= _pixel_width) { + (*x)->hide(); + } else { + (*x)->show(); + } + } + move_step_edit_cursor (_step_edit_cursor_position); set_step_edit_cursor_width (_step_edit_cursor_width); } @@ -1788,28 +1824,37 @@ MidiRegionView::add_canvas_patch_change (MidiModel::PatchChangePtr patch, const double const height = midi_stream_view()->contents_height(); boost::shared_ptr patch_change = boost::shared_ptr( - new CanvasPatchChange(*this, *_note_group, + new CanvasPatchChange(*this, *group, displaytext, height, x, 1.0, - _model_name, - _custom_device_mode, + instrument_info(), patch, active_channel) ); - // Show unless patch change is beyond the region bounds - if (region_frames < 0 || region_frames >= _region->length()) { - patch_change->hide(); + if (patch_change->width() < _pixel_width) { + // Show unless patch change is beyond the region bounds + if (region_frames < 0 || region_frames >= _region->length()) { + patch_change->hide(); + } else { + patch_change->show(); + } } else { - patch_change->show(); + patch_change->hide (); } _patch_changes.push_back (patch_change); } -void -MidiRegionView::get_patch_key_at (Evoral::MusicalTime time, uint8_t channel, MIDI::Name::PatchPrimaryKey& key) +MIDI::Name::PatchPrimaryKey +MidiRegionView::patch_change_to_patch_key (MidiModel::PatchChangePtr p) +{ + return MIDI::Name::PatchPrimaryKey (p->program(), p->bank()); +} + +void +MidiRegionView::get_patch_key_at (double time, uint8_t channel, MIDI::Name::PatchPrimaryKey& key) { MidiModel::PatchChanges::iterator i = _model->patch_change_lower_bound (time); while (i != _model->patch_changes().end() && (*i)->channel() != channel) { @@ -1826,7 +1871,6 @@ MidiRegionView::get_patch_key_at (Evoral::MusicalTime time, uint8_t channel, MID assert (key.is_sane()); } - void MidiRegionView::change_patch_change (CanvasPatchChange& pc, const MIDI::Name::PatchPrimaryKey& new_patch) { @@ -1925,8 +1969,7 @@ void MidiRegionView::previous_patch (CanvasPatchChange& patch) { if (patch.patch()->program() < 127) { - MIDI::Name::PatchPrimaryKey key; - get_patch_key_at (patch.patch()->time(), patch.patch()->channel(), key); + MIDI::Name::PatchPrimaryKey key = patch_change_to_patch_key (patch.patch()); key.program_number++; change_patch_change (patch, key); } @@ -1936,19 +1979,17 @@ void MidiRegionView::next_patch (CanvasPatchChange& patch) { if (patch.patch()->program() > 0) { - MIDI::Name::PatchPrimaryKey key; - get_patch_key_at (patch.patch()->time(), patch.patch()->channel(), key); + MIDI::Name::PatchPrimaryKey key = patch_change_to_patch_key (patch.patch()); key.program_number--; change_patch_change (patch, key); } } void -MidiRegionView::previous_bank (CanvasPatchChange& patch) +MidiRegionView::next_bank (CanvasPatchChange& patch) { if (patch.patch()->program() < 127) { - MIDI::Name::PatchPrimaryKey key; - get_patch_key_at (patch.patch()->time(), patch.patch()->channel(), key); + MIDI::Name::PatchPrimaryKey key = patch_change_to_patch_key (patch.patch()); if (key.bank_number > 0) { key.bank_number--; change_patch_change (patch, key); @@ -1957,11 +1998,10 @@ MidiRegionView::previous_bank (CanvasPatchChange& patch) } void -MidiRegionView::next_bank (CanvasPatchChange& patch) +MidiRegionView::previous_bank (CanvasPatchChange& patch) { if (patch.patch()->program() > 0) { - MIDI::Name::PatchPrimaryKey key; - get_patch_key_at (patch.patch()->time(), patch.patch()->channel(), key); + MIDI::Name::PatchPrimaryKey key = patch_change_to_patch_key (patch.patch()); if (key.bank_number < 127) { key.bank_number++; change_patch_change (patch, key); @@ -2877,7 +2917,7 @@ void MidiRegionView::change_velocities (bool up, bool fine, bool allow_smush, bool all_together) { int8_t delta; - int8_t value; + int8_t value = 0; if (_selection.empty()) { return; @@ -3125,18 +3165,42 @@ MidiRegionView::note_left (ArdourCanvas::CanvasNoteEvent*) } void -MidiRegionView::patch_entered (ArdourCanvas::CanvasPatchChange* ev) +MidiRegionView::patch_entered (ArdourCanvas::CanvasPatchChange* p) { ostringstream s; /* XXX should get patch name if we can */ - s << _("Bank:") << (ev->patch()->bank() + MIDI_BP_ZERO) << '\n' << _("Program:") << ((int) ev->patch()->program()) + MIDI_BP_ZERO << '\n' << _("Channel:") << ((int) ev->patch()->channel() + 1); + s << _("Bank:") << (p->patch()->bank() + MIDI_BP_ZERO) << '\n' + << _("Program:") << ((int) p->patch()->program()) + MIDI_BP_ZERO << '\n' + << _("Channel:") << ((int) p->patch()->channel() + 1); show_verbose_cursor (s.str(), 10, 20); + p->grab_focus(); } void MidiRegionView::patch_left (ArdourCanvas::CanvasPatchChange *) { trackview.editor().verbose_cursor()->hide (); + /* focus will transfer back via the enter-notify event sent to this + * midi region view. + */ +} + +void +MidiRegionView::sysex_entered (ArdourCanvas::CanvasSysEx* p) +{ + ostringstream s; + s << p->text(); + show_verbose_cursor (s.str(), 10, 20); + p->grab_focus(); +} + +void +MidiRegionView::sysex_left (ArdourCanvas::CanvasSysEx *) +{ + trackview.editor().verbose_cursor()->hide (); + /* focus will transfer back via the enter-notify event sent to this + * midi region view. + */ } void @@ -3196,6 +3260,7 @@ MidiRegionView::midi_channel_mode_changed(ChannelMode mode, uint16_t mask) } _last_channel_selection = mask; + _last_channel_mode = mode; _patch_changes.clear (); display_patch_changes (); @@ -3650,6 +3715,14 @@ MidiRegionView::data_recorded (boost::weak_ptr w) Evoral::MIDIEvent const ev (*i, false); assert (ev.buffer ()); + if(ev.is_channel_event()) { + if (_last_channel_mode == FilterChannels) { + if(((uint16_t(1) << ev.channel()) & _last_channel_selection) == 0) { + continue; + } + } + } + /* ev.time() is in session frames, so (ev.time() - converter.origin_b()) is frames from the start of the source, and so time_beats is in terms of the source. @@ -3709,7 +3782,10 @@ MidiRegionView::trim_front_ending () void MidiRegionView::edit_patch_change (ArdourCanvas::CanvasPatchChange* pc) { - PatchChangeDialog d (&_source_relative_time_converter, trackview.session(), *pc->patch (), _model_name, _custom_device_mode, Gtk::Stock::APPLY); + PatchChangeDialog d (&_source_relative_time_converter, trackview.session(), *pc->patch (), instrument_info(), Gtk::Stock::APPLY); + + d.set_position (Gtk::WIN_POS_MOUSE); + if (d.run () != Gtk::RESPONSE_ACCEPT) { return; } @@ -3717,6 +3793,16 @@ MidiRegionView::edit_patch_change (ArdourCanvas::CanvasPatchChange* pc) change_patch_change (pc->patch(), d.patch ()); } +void +MidiRegionView::delete_sysex (CanvasSysEx* sysex) +{ + MidiModel::SysExDiffCommand* c = _model->new_sysex_diff_command (_("delete sysex")); + c->remove (sysex->sysex()); + _model->apply_command (*trackview.session(), c); + + _sys_exes.clear (); + display_sysexes(); +} void MidiRegionView::show_verbose_cursor (boost::shared_ptr n) const