get the MIDI list editor working a little better and a little more

git-svn-id: svn://localhost/ardour2/branches/3.0@6453 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2010-01-05 03:52:30 +00:00
parent a23811502c
commit 51aec9a331
4 changed files with 89 additions and 16 deletions

View File

@ -16,6 +16,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <cmath>
#include "evoral/midi_util.h"
#include "ardour/midi_region.h"
@ -40,6 +41,9 @@ MidiListEditor::MidiListEditor (Session* s, boost::shared_ptr<MidiRegion> r)
model = ListStore::create (columns);
view.set_model (model);
view.signal_key_press_event().connect (sigc::mem_fun (*this, &MidiListEditor::key_press));
view.signal_key_release_event().connect (sigc::mem_fun (*this, &MidiListEditor::key_release));
view.append_column (_("Start"), columns.start);
view.append_column (_("Channel"), columns.channel);
view.append_column (_("Num"), columns.note);
@ -73,6 +77,47 @@ MidiListEditor::~MidiListEditor ()
{
}
bool
MidiListEditor::key_press (GdkEventKey* ev)
{
return true;
}
bool
MidiListEditor::key_release (GdkEventKey* ev)
{
switch (ev->keyval) {
case GDK_Delete:
delete_selected_note ();
break;
default:
break;
}
return true;
}
void
MidiListEditor::delete_selected_note ()
{
Glib::RefPtr<TreeSelection> selection = view.get_selection();
TreeView::Selection::ListHandle_Path rows = selection->get_selected_rows ();
if (rows.empty()) {
return;
}
TreeView::Selection::ListHandle_Path::iterator i = rows.begin();
TreeIter iter;
/* selection mode is single, so rows.begin() is it */
if ((iter = model->get_iter (*i))) {
boost::shared_ptr<NoteType> note = (*iter)[columns._note];
cerr << "Would have deleted " << *note << endl;
}
}
void
MidiListEditor::edited (const Glib::ustring& path, const Glib::ustring& /* text */)
{
@ -89,6 +134,8 @@ MidiListEditor::edited (const Glib::ustring& path, const Glib::ustring& /* text
cerr << "Edited " << *note << endl;
redisplay_model ();
/* keep selected row(s), move cursor there, to allow us to continue editing */
}
void
@ -101,34 +148,45 @@ MidiListEditor::redisplay_model ()
MidiModel::Notes notes = region->midi_source(0)->model()->notes();
TreeModel::Row row;
stringstream ss;
for (MidiModel::Notes::iterator i = notes.begin(); i != notes.end(); ++i) {
row = *(model->append());
row[columns.channel] = (*i)->channel();
row[columns.note_name] = _("Note");
row[columns.channel] = (*i)->channel() + 1;
row[columns.note_name] = Evoral::midi_note_name ((*i)->note());
row[columns.note] = (*i)->note();
row[columns.velocity] = (*i)->velocity();
BBT_Time bbt;
BBT_Time dur;
stringstream ss;
double dur;
bbt.bars = 0;
bbt.beats = (uint32_t) floor ((*i)->time());
bbt.ticks = (uint32_t) lrint (fmod ((*i)->time(), 1.0) * Meter::ticks_per_beat);
_session->tempo_map().bbt_time (region->position(), bbt);
dur.bars = 0;
dur.beats = floor ((*i)->time());
dur.ticks = 0;
_session->tempo_map().bbt_duration_at (region->position(), dur, 0);
ss.str ("");
ss << bbt;
row[columns.start] = ss.str();
ss << dur;
bbt.bars = 0;
dur = (*i)->end_time() - (*i)->time();
bbt.beats = floor (dur);
bbt.ticks = (uint32_t) lrint (fmod (dur, 1.0) * Meter::ticks_per_beat);
_session->tempo_map().bbt_duration_at (region->position(), bbt, 0);
ss.str ("");
ss << bbt;
row[columns.length] = ss.str();
bbt.bars = 0;
bbt.beats = (uint32_t) floor ((*i)->end_time());
bbt.ticks = (uint32_t) lrint (fmod ((*i)->end_time(), 1.0) * Meter::ticks_per_beat);
_session->tempo_map().bbt_time (region->position(), bbt);
/* XXX get end point */
ss.str ("");
ss << bbt;
row[columns.end] = ss.str();

View File

@ -54,7 +54,7 @@ class MidiListEditor : public ArdourDialog
add (start);
add (length);
add (end);
add (note);
add (_note);
};
Gtk::TreeModelColumn<uint8_t> channel;
Gtk::TreeModelColumn<uint8_t> note;
@ -75,6 +75,11 @@ class MidiListEditor : public ArdourDialog
void edited (const Glib::ustring&, const Glib::ustring&);
void redisplay_model ();
bool key_press (GdkEventKey* ev);
bool key_release (GdkEventKey* ev);
void delete_selected_note ();
};
#endif /* __ardour_gtk2_midi_list_editor_h_ */

View File

@ -89,6 +89,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
, _pressed_button(0)
, _sort_needed (true)
, _optimization_iterator (_events.end())
, _list_editor (0)
{
_note_group->raise_to_top();
}
@ -110,6 +111,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
, _pressed_button(0)
, _sort_needed (true)
, _optimization_iterator (_events.end())
, _list_editor (0)
{
_note_group->raise_to_top();
@ -132,6 +134,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other)
, _pressed_button(0)
, _sort_needed (true)
, _optimization_iterator (_events.end())
, _list_editor (0)
{
Gdk::Color c;
int r,g,b,a;
@ -157,6 +160,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<M
, _pressed_button(0)
, _sort_needed (true)
, _optimization_iterator (_events.end())
, _list_editor (0)
{
Gdk::Color c;
int r,g,b,a;
@ -517,8 +521,10 @@ MidiRegionView::canvas_event(GdkEvent* ev)
void
MidiRegionView::show_list_editor ()
{
MidiListEditor* mle = new MidiListEditor (trackview.session(), midi_region());
mle->show ();
if (!_list_editor) {
_list_editor = new MidiListEditor (trackview.session(), midi_region());
}
_list_editor->present ();
}
/** Add a note to the model, and the view, at a canvas (click) coordinate.
@ -938,6 +944,8 @@ MidiRegionView::~MidiRegionView ()
{
in_destructor = true;
delete _list_editor;
RegionViewGoingAway (this); /* EMIT_SIGNAL */
if (_active_notes) {

View File

@ -63,6 +63,7 @@ class GhostRegion;
class AutomationTimeAxisView;
class AutomationRegionView;
class MidiCutBuffer;
class MidiListEditor;
class MidiRegionView : public RegionView
{
@ -397,6 +398,7 @@ class MidiRegionView : public RegionView
void update_note (ArdourCanvas::CanvasNote*);
void update_hit (ArdourCanvas::CanvasHit*);
MidiListEditor* _list_editor;
};