13
0

Add note edit dialog. Fixes #3346.

git-svn-id: svn://localhost/ardour2/branches/3.0@7625 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2010-08-14 02:00:50 +00:00
parent 4e2d805c9d
commit 439d13535e
8 changed files with 246 additions and 6 deletions

View File

@ -0,0 +1,156 @@
/*
Copyright (C) 2010 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 <gtkmm/stock.h>
#include <gtkmm/table.h>
#include "ardour/midi_model.h"
#include "edit_note_dialog.h"
#include "canvas-note-event.h"
#include "midi_region_view.h"
using namespace Gtk;
/**
* EditNoteDialog constructor.
*
* @param n Note to edit.
*/
EditNoteDialog::EditNoteDialog (MidiRegionView* rv, Gnome::Canvas::CanvasNoteEvent* ev)
: ArdourDialog (_("Note"))
, _region_view (rv)
, _event (ev)
, _time_clock (X_("notetime"), true, X_("NoteTimeClock"), true, false)
, _length_clock (X_("notelength"), true, X_("NoteLengthClock"), true, false, true)
{
Table* table = manage (new Table (4, 2));
table->set_spacings (6);
int r = 0;
Label* l = manage (new Label (_("Channel")));
l->set_alignment (0, 0.5);
table->attach (*l, 0, 1, r, r + 1);
table->attach (_channel, 1, 2, r, r + 1);
++r;
_channel.set_range (1, 16);
_channel.set_increments (1, 2);
_channel.set_value (ev->note()->channel () + 1);
l = manage (new Label (_("Pitch")));
l->set_alignment (0, 0.5);
table->attach (*l, 0, 1, r, r + 1);
table->attach (_pitch, 1, 2, r, r + 1);
++r;
_pitch.set_range (0, 127);
_pitch.set_increments (1, 10);
_pitch.set_value (ev->note()->note ());
l = manage (new Label (_("Velocity")));
l->set_alignment (0, 0.5);
table->attach (*l, 0, 1, r, r + 1);
table->attach (_velocity, 1, 2, r, r + 1);
++r;
_velocity.set_range (0, 127);
_velocity.set_increments (1, 10);
_velocity.set_value (ev->note()->velocity ());
l = manage (new Label (_("Time")));
l->set_alignment (0, 0.5);
table->attach (*l, 0, 1, r, r + 1);
table->attach (_time_clock, 1, 2, r, r + 1);
++r;
_time_clock.set_session (_region_view->get_trackview().session ());
_time_clock.set_mode (AudioClock::BBT);
_time_clock.set (_region_view->time_converter().to (ev->note()->time ()), true);
l = manage (new Label (_("Length")));
l->set_alignment (0, 0.5);
table->attach (*l, 0, 1, r, r + 1);
table->attach (_length_clock, 1, 2, r, r + 1);
++r;
_length_clock.set_session (_region_view->get_trackview().session ());
_length_clock.set_mode (AudioClock::BBT);
_length_clock.set (_region_view->time_converter().to (ev->note()->length ()), true);
get_vbox()->pack_start (*table);
add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
add_button (Gtk::Stock::APPLY, Gtk::RESPONSE_ACCEPT);
set_default_response (Gtk::RESPONSE_ACCEPT);
show_all ();
}
int
EditNoteDialog::run ()
{
int const r = Dialog::run ();
if (r != RESPONSE_ACCEPT) {
return r;
}
_region_view->start_diff_command (_("edit note"));
bool had_change = false;
if (_channel.get_value_as_int() - 1 != _event->note()->channel()) {
_region_view->change_note_channel (_event, _channel.get_value_as_int () - 1);
had_change = true;
}
if (_pitch.get_value_as_int() != _event->note()->note()) {
_region_view->change_note_note (_event, _pitch.get_value_as_int (), false);
had_change = true;
}
if (_velocity.get_value_as_int() != _event->note()->velocity()) {
_region_view->change_note_velocity (_event, _velocity.get_value_as_int (), false);
had_change = true;
}
double const t = _region_view->time_converter().from (_time_clock.current_time ());
if (t != _event->note()->time()) {
_region_view->change_note_time (_event, t);
had_change = true;
}
double const d = _region_view->time_converter().from (_length_clock.current_duration ());
if (d != _event->note()->length()) {
_region_view->change_note_length (_event, d);
had_change = true;
}
if (!had_change) {
_region_view->abort_command ();
}
_region_view->apply_diff ();
_event->set_selected (_event->selected()); // change color
return r;
}

View File

@ -0,0 +1,48 @@
/*
Copyright (C) 2010 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 <gtkmm/spinbutton.h>
#include "ardour/midi_model.h"
#include "ardour_dialog.h"
#include "audio_clock.h"
class MidiRegionView;
namespace Gnome {
namespace Canvas {
class CanvasNoteEvent;
}
}
class EditNoteDialog : public ArdourDialog
{
public:
EditNoteDialog (MidiRegionView *, Gnome::Canvas::CanvasNoteEvent *);
int run ();
private:
MidiRegionView* _region_view;
Gnome::Canvas::CanvasNoteEvent* _event;
Gtk::SpinButton _channel;
Gtk::SpinButton _pitch;
Gtk::SpinButton _velocity;
AudioClock _time_clock;
AudioClock _length_clock;
};

View File

@ -1461,6 +1461,7 @@ public:
void edit_tempo_marker (ArdourCanvas::Item*); void edit_tempo_marker (ArdourCanvas::Item*);
void edit_meter_marker (ArdourCanvas::Item*); void edit_meter_marker (ArdourCanvas::Item*);
void edit_control_point (ArdourCanvas::Item*); void edit_control_point (ArdourCanvas::Item*);
void edit_note (ArdourCanvas::Item *);
void marker_menu_edit (); void marker_menu_edit ();
void marker_menu_remove (); void marker_menu_remove ();

View File

@ -54,6 +54,7 @@
#include "control_point_dialog.h" #include "control_point_dialog.h"
#include "editor_drag.h" #include "editor_drag.h"
#include "automation_region_view.h" #include "automation_region_view.h"
#include "edit_note_dialog.h"
#include "ardour/types.h" #include "ardour/types.h"
#include "ardour/profile.h" #include "ardour/profile.h"
@ -1150,6 +1151,10 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
edit_control_point (item); edit_control_point (item);
break; break;
case NoteItem:
edit_note (item);
break;
default: default:
break; break;
} }
@ -1989,6 +1994,19 @@ Editor::edit_control_point (ArdourCanvas::Item* item)
p->line().modify_point_y (*p, d.get_y_fraction ()); p->line().modify_point_y (*p, d.get_y_fraction ());
} }
void
Editor::edit_note (ArdourCanvas::Item* item)
{
ArdourCanvas::CanvasNoteEvent* e = dynamic_cast<ArdourCanvas::CanvasNoteEvent*> (item);
assert (e);
EditNoteDialog d (&e->region_view(), e);
d.set_position (Gtk::WIN_POS_MOUSE);
ensure_float (d);
d.run ();
}
void void
Editor::visible_order_range (int* low, int* high) const Editor::visible_order_range (int* low, int* high) const

View File

@ -2260,6 +2260,12 @@ MidiRegionView::commit_resizing (ArdourCanvas::CanvasNote* primary, bool at_fron
apply_diff(); apply_diff();
} }
void
MidiRegionView::change_note_channel (CanvasNoteEvent* event, int8_t channel)
{
diff_add_change (event, MidiModel::DiffCommand::Channel, (uint8_t) channel);
}
void void
MidiRegionView::change_note_velocity(CanvasNoteEvent* event, int8_t velocity, bool relative) MidiRegionView::change_note_velocity(CanvasNoteEvent* event, int8_t velocity, bool relative)
{ {
@ -2386,6 +2392,12 @@ MidiRegionView::change_note_time (CanvasNoteEvent* event, Evoral::MusicalTime de
diff_add_change (event, MidiModel::DiffCommand::StartTime, new_time); diff_add_change (event, MidiModel::DiffCommand::StartTime, new_time);
} }
void
MidiRegionView::change_note_length (CanvasNoteEvent* event, Evoral::MusicalTime t)
{
diff_add_change (event, MidiModel::DiffCommand::Length, t);
}
void void
MidiRegionView::change_velocities (bool up, bool fine, bool allow_smush) MidiRegionView::change_velocities (bool up, bool fine, bool allow_smush)
{ {

View File

@ -64,6 +64,7 @@ class AutomationTimeAxisView;
class AutomationRegionView; class AutomationRegionView;
class MidiCutBuffer; class MidiCutBuffer;
class MidiListEditor; class MidiListEditor;
class EditNoteDialog;
class MidiRegionView : public RegionView class MidiRegionView : public RegionView
{ {
@ -224,12 +225,6 @@ class MidiRegionView : public RegionView
void update_resizing (ArdourCanvas::CanvasNote *, bool, double, bool); void update_resizing (ArdourCanvas::CanvasNote *, bool, double, bool);
void commit_resizing (ArdourCanvas::CanvasNote *, bool, double, bool); void commit_resizing (ArdourCanvas::CanvasNote *, bool, double, bool);
/** Adjust the velocity on a note, and the selection if applicable.
* @param velocity the relative or absolute velocity
* @param relative whether velocity is relative or absolute
*/
void change_velocity(ArdourCanvas::CanvasNoteEvent* ev, int8_t velocity, bool relative=false);
/** Change the channel of the selection. /** Change the channel of the selection.
* @param channel - the channel number of the new channel, zero-based * @param channel - the channel number of the new channel, zero-based
*/ */
@ -306,6 +301,9 @@ class MidiRegionView : public RegionView
void reset_width_dependent_items (double pixel_width); void reset_width_dependent_items (double pixel_width);
private: private:
friend class EditNoteDialog;
/** Play the NoteOn event of the given note immediately /** Play the NoteOn event of the given note immediately
* and schedule the playback of the corresponding NoteOff event. * and schedule the playback of the corresponding NoteOff event.
*/ */
@ -325,9 +323,11 @@ class MidiRegionView : public RegionView
void midi_channel_mode_changed(ARDOUR::ChannelMode mode, uint16_t mask); 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 midi_patch_settings_changed(std::string model, std::string custom_device_mode);
void change_note_channel (ArdourCanvas::CanvasNoteEvent *, int8_t);
void change_note_velocity(ArdourCanvas::CanvasNoteEvent* ev, int8_t vel, 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_note(ArdourCanvas::CanvasNoteEvent* ev, int8_t note, bool relative=false);
void change_note_time(ArdourCanvas::CanvasNoteEvent* ev, ARDOUR::MidiModel::TimeType, bool relative=false); void change_note_time(ArdourCanvas::CanvasNoteEvent* ev, ARDOUR::MidiModel::TimeType, bool relative=false);
void change_note_length (ArdourCanvas::CanvasNoteEvent *, ARDOUR::MidiModel::TimeType);
void trim_note(ArdourCanvas::CanvasNoteEvent* ev, ARDOUR::MidiModel::TimeType start_delta, void trim_note(ArdourCanvas::CanvasNoteEvent* ev, ARDOUR::MidiModel::TimeType start_delta,
ARDOUR::MidiModel::TimeType end_delta); ARDOUR::MidiModel::TimeType end_delta);

View File

@ -91,6 +91,10 @@ class RegionView : public TimeAxisViewItem
static PBD::Signal1<void,RegionView*> RegionViewGoingAway; static PBD::Signal1<void,RegionView*> RegionViewGoingAway;
ARDOUR::BeatsFramesConverter const & time_converter () {
return _time_converter;
}
protected: protected:
/** Allows derived types to specify their visibility requirements /** Allows derived types to specify their visibility requirements

View File

@ -66,6 +66,7 @@ gtk2_ardour_sources = [
'crossfade_view.cc', 'crossfade_view.cc',
'curvetest.cc', 'curvetest.cc',
'diamond.cc', 'diamond.cc',
'edit_note_dialog.cc',
'editing.cc', 'editing.cc',
'editor.cc', 'editor.cc',
'editor_actions.cc', 'editor_actions.cc',