From cab3072f83bb2e959e5ece5e344c568caf474be6 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 13 Jun 2011 14:48:48 +0000 Subject: [PATCH] add MIDI channel editing for current note selection, bound to "c" by default git-svn-id: svn://localhost/ardour2/branches/3.0@9718 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/midi_channel_dialog.cc | 41 +++++++++++++++ gtk2_ardour/midi_channel_dialog.h | 37 ++++++++++++++ gtk2_ardour/midi_channel_selector.h | 3 +- gtk2_ardour/midi_region_view.cc | 79 ++++++++++++++++++++++++++--- gtk2_ardour/midi_region_view.h | 3 +- gtk2_ardour/wscript | 1 + 6 files changed, 156 insertions(+), 8 deletions(-) create mode 100644 gtk2_ardour/midi_channel_dialog.cc create mode 100644 gtk2_ardour/midi_channel_dialog.h diff --git a/gtk2_ardour/midi_channel_dialog.cc b/gtk2_ardour/midi_channel_dialog.cc new file mode 100644 index 0000000000..f827037817 --- /dev/null +++ b/gtk2_ardour/midi_channel_dialog.cc @@ -0,0 +1,41 @@ +/* + Copyright (C) 2011 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include + +#include "midi_channel_dialog.h" + +#include "i18n.h" + +using namespace Gtk; + +MidiChannelDialog::MidiChannelDialog (uint8_t active_channel) + : ArdourDialog (X_("MIDI Channel Chooser"), true) + , selector (active_channel) +{ + selector.show_all (); + get_vbox()->pack_start (selector); + add_button (Stock::CANCEL, RESPONSE_CANCEL); + add_button (Stock::OK, RESPONSE_OK); +} + +uint8_t +MidiChannelDialog::active_channel () const +{ + return selector.get_active_channel(); +} diff --git a/gtk2_ardour/midi_channel_dialog.h b/gtk2_ardour/midi_channel_dialog.h new file mode 100644 index 0000000000..fcf239272c --- /dev/null +++ b/gtk2_ardour/midi_channel_dialog.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2011 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __gtk2_ardour_midi_channel_dialog_h__ +#define __gtk2_ardour_midi_channel_dialog_h__ + +#include + +#include "ardour_dialog.h" +#include "midi_channel_selector.h" + +class MidiChannelDialog : public ArdourDialog +{ + public: + MidiChannelDialog (uint8_t active_channel = 0); + uint8_t active_channel() const; + + private: + SingleMidiChannelSelector selector; +}; + +#endif /* __gtk2_ardour_midi_channel_dialog_h__ */ diff --git a/gtk2_ardour/midi_channel_selector.h b/gtk2_ardour/midi_channel_selector.h index 8bcf704ca4..c5e6a5a378 100644 --- a/gtk2_ardour/midi_channel_selector.h +++ b/gtk2_ardour/midi_channel_selector.h @@ -23,12 +23,13 @@ #include #include "boost/shared_ptr.hpp" #include "sigc++/trackable.h" + #include "gtkmm/table.h" #include "gtkmm/button.h" #include "gtkmm/label.h" #include "gtkmm2ext/stateful_button.h" -#include "ardour/types.h" +#include "ardour/types.h" class MidiChannelSelector : public Gtk::Table { diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 8553900278..54f6a2c59a 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -54,6 +54,7 @@ #include "ghostregion.h" #include "gui_thread.h" #include "keyboard.h" +#include "midi_channel_dialog.h" #include "midi_cut_buffer.h" #include "midi_list_editor.h" #include "midi_region_view.h" @@ -769,6 +770,9 @@ MidiRegionView::key_press (GdkEventKey* ev) } else if (ev->keyval == GDK_Control_L) { return true; + } else if (ev->keyval == GDK_c) { + channel_edit (); + return true; } return false; @@ -784,6 +788,53 @@ MidiRegionView::key_release (GdkEventKey* ev) return false; } +void +MidiRegionView::channel_edit () +{ + bool first = true; + bool mixed = false; + uint8_t current_channel; + + if (_selection.empty()) { + return; + } + + for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) { + Selection::iterator next = i; + if (first) { + current_channel = (*i)->note()->channel (); + first = false; + } else { + if (current_channel != (*i)->note()->channel()) { + mixed = true; + } + } + } + + MidiChannelDialog channel_dialog (current_channel); + int ret = channel_dialog.run (); + + switch (ret) { + case Gtk::RESPONSE_OK: + break; + default: + return; + } + + uint8_t new_channel = channel_dialog.active_channel (); + + start_note_diff_command (_("channel edit")); + + for (Selection::iterator i = _selection.begin(); i != _selection.end(); ) { + Selection::iterator next = i; + ++next; + change_note_channel (*i, new_channel); + i = next; + } + + apply_diff (); +} + void MidiRegionView::show_list_editor () { @@ -2469,12 +2520,6 @@ MidiRegionView::commit_resizing (ArdourCanvas::CanvasNoteEvent* primary, bool at apply_diff(); } -void -MidiRegionView::change_note_channel (CanvasNoteEvent* event, int8_t channel) -{ - note_diff_add_change (event, MidiModel::NoteDiffCommand::Channel, (uint8_t) channel); -} - void MidiRegionView::change_note_velocity(CanvasNoteEvent* event, int8_t velocity, bool relative) { @@ -2579,6 +2624,28 @@ MidiRegionView::trim_note (CanvasNoteEvent* event, Evoral::MusicalTime front_del } } +void +MidiRegionView::change_note_channel (CanvasNoteEvent* event, int8_t chn, bool relative) +{ + uint8_t new_channel; + + if (relative) { + if (chn < 0.0) { + if (event->note()->channel() < -chn) { + new_channel = 0; + } else { + new_channel = event->note()->channel() + chn; + } + } else { + new_channel = event->note()->channel() + chn; + } + } else { + new_channel = (uint8_t) chn; + } + + note_diff_add_change (event, MidiModel::NoteDiffCommand::Channel, new_channel); +} + void MidiRegionView::change_note_time (CanvasNoteEvent* event, Evoral::MusicalTime delta, bool relative) { diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index 2da45a7ce3..116f210ee1 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -264,6 +264,7 @@ public: void change_velocities (bool up, bool fine, bool allow_smush); void transpose (bool up, bool fine, bool allow_smush); void nudge_notes (bool forward); + void channel_edit (); void show_list_editor (); @@ -318,7 +319,7 @@ private: void midi_channel_mode_changed(ARDOUR::ChannelMode mode, uint16_t mask); void midi_patch_settings_changed(std::string model, std::string custom_device_mode); - void change_note_channel (ArdourCanvas::CanvasNoteEvent *, int8_t); + void change_note_channel (ArdourCanvas::CanvasNoteEvent *, int8_t, bool relative=false); void change_note_velocity(ArdourCanvas::CanvasNoteEvent* ev, int8_t vel, bool relative=false); void change_note_note(ArdourCanvas::CanvasNoteEvent* ev, int8_t note, bool relative=false); void change_note_time(ArdourCanvas::CanvasNoteEvent* ev, ARDOUR::MidiModel::TimeType, bool relative=false); diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index d357d1e277..616bcd66df 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -133,6 +133,7 @@ gtk2_ardour_sources = [ 'main.cc', 'marker.cc', 'midi_automation_line.cc', + 'midi_channel_dialog.cc', 'midi_channel_selector.cc', 'midi_cut_buffer.cc', 'midi_list_editor.cc',