diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 8229c9bc29..592da5aa91 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -61,6 +61,7 @@ #include "midi_streamview.h" #include "midi_time_axis.h" #include "midi_util.h" +#include "midi_velocity_dialog.h" #include "mouse_cursors.h" #include "note_player.h" #include "public_editor.h" @@ -736,7 +737,7 @@ MidiRegionView::key_press (GdkEventKey* ev) bool allow_smush = Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier); bool fine = !Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier); - bool together = Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier); + bool together = Keyboard::modifier_state_contains (ev->state, Keyboard::Level4Modifier); if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) { change_velocities (true, fine, allow_smush, together); @@ -749,14 +750,13 @@ MidiRegionView::key_press (GdkEventKey* ev) bool allow_smush = Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier); bool fine = !Keyboard::modifier_state_contains (ev->state, Keyboard::SecondaryModifier); - bool together = Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier); + bool together = Keyboard::modifier_state_contains (ev->state, Keyboard::Level4Modifier); - if (Keyboard::no_modifiers_active (ev->state)) { - transpose (false, fine, allow_smush); - } else { + if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)) { change_velocities (false, fine, allow_smush, together); + } else { + transpose (false, fine, allow_smush); } - return true; } else if (ev->keyval == GDK_Left && unmodified) { @@ -772,6 +772,10 @@ MidiRegionView::key_press (GdkEventKey* ev) } else if (ev->keyval == GDK_c && unmodified) { channel_edit (); return true; + + } else if (ev->keyval == GDK_v && unmodified) { + velocity_edit (); + return true; } return false; @@ -790,20 +794,15 @@ MidiRegionView::key_release (GdkEventKey* ev) void MidiRegionView::channel_edit () { - bool first = true; - uint8_t current_channel = 0; - if (_selection.empty()) { return; } - - for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) { - if (first) { - current_channel = (*i)->note()->channel (); - first = false; - } - } + /* pick a note somewhat at random (since Selection is a set<>) to + * provide the "current" channel for the dialog. + */ + + uint8_t current_channel = (*_selection.begin())->note()->channel (); MidiChannelDialog channel_dialog (current_channel); int ret = channel_dialog.run (); @@ -828,6 +827,42 @@ MidiRegionView::channel_edit () apply_diff (); } +void +MidiRegionView::velocity_edit () +{ + if (_selection.empty()) { + return; + } + + /* pick a note somewhat at random (since Selection is a set<>) to + * provide the "current" velocity for the dialog. + */ + + uint8_t current_velocity = (*_selection.begin())->note()->velocity (); + MidiVelocityDialog velocity_dialog (current_velocity); + int ret = velocity_dialog.run (); + + switch (ret) { + case Gtk::RESPONSE_OK: + break; + default: + return; + } + + uint8_t new_velocity = velocity_dialog.velocity (); + + start_note_diff_command (_("velocity edit")); + + for (Selection::iterator i = _selection.begin(); i != _selection.end(); ) { + Selection::iterator next = i; + ++next; + change_note_velocity (*i, new_velocity, false); + i = next; + } + + apply_diff (); +} + void MidiRegionView::show_list_editor () { @@ -1282,6 +1317,8 @@ MidiRegionView::~MidiRegionView () end_write(); } + _selection_cleared_connection.disconnect (); + _selection.clear(); clear_events(); diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index 546d01ce23..a6750ef123 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -278,6 +278,7 @@ public: void transpose (bool up, bool fine, bool allow_smush); void nudge_notes (bool forward); void channel_edit (); + void velocity_edit (); void show_list_editor (); diff --git a/gtk2_ardour/midi_velocity_dialog.cc b/gtk2_ardour/midi_velocity_dialog.cc new file mode 100644 index 0000000000..ce90862de3 --- /dev/null +++ b/gtk2_ardour/midi_velocity_dialog.cc @@ -0,0 +1,52 @@ +/* + Copyright (C) 2012 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_velocity_dialog.h" + +#include "i18n.h" + +using namespace Gtk; + +MidiVelocityDialog::MidiVelocityDialog (uint8_t current_velocity) + : ArdourDialog (X_("Note Velocity"), true) + , adjustment (current_velocity, 0, 127, 1, 16) + , spinner (adjustment) + , label (_("New velocity")) +{ + spinner.show (); + label.show (); + packer.show (); + + packer.pack_start (label, false, false); + packer.pack_start (spinner, false, false); + + get_vbox()->pack_start (packer); + + add_button (Stock::CANCEL, RESPONSE_CANCEL); + add_button (Stock::OK, RESPONSE_OK); + + spinner.signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &MidiVelocityDialog::response), Gtk::RESPONSE_OK)); +} + +uint8_t +MidiVelocityDialog::velocity () const +{ + return (uint8_t) adjustment.get_value(); +} diff --git a/gtk2_ardour/midi_velocity_dialog.h b/gtk2_ardour/midi_velocity_dialog.h new file mode 100644 index 0000000000..b01a6fde79 --- /dev/null +++ b/gtk2_ardour/midi_velocity_dialog.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 2012 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_velocity_dialog_h__ +#define __gtk2_ardour_midi_velocity_dialog_h__ + +#include + +#include +#include + +#include "ardour_dialog.h" + + +class MidiVelocityDialog : public ArdourDialog +{ + public: + MidiVelocityDialog (uint8_t current_velocity = 0); + uint8_t velocity() const; + + private: + Gtk::Adjustment adjustment; + Gtk::SpinButton spinner; + Gtk::Label label; + Gtk::HBox packer; +}; + +#endif /* __gtk2_ardour_midi_velocity_dialog_h__ */ diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index 2fb8f0ddd9..aa24c60d88 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -147,6 +147,7 @@ gtk2_ardour_sources = [ 'midi_streamview.cc', 'midi_time_axis.cc', 'midi_tracer.cc', + 'midi_velocity_dialog.cc', 'missing_file_dialog.cc', 'missing_plugin_dialog.cc', 'mixer_actor.cc',