From 5182f0770cca50cbb7c8fe419b2e64af02525553 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 11 Aug 2010 18:21:37 +0000 Subject: add a first hack at a step edit cursor (to be changed); add program+bank stubs (non-functional for the foreseeable future); fix up step edit changes propagating across all MIDI tracks; make program change "flags" change height along with track git-svn-id: svn://localhost/ardour2/branches/3.0@7598 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/canvas-flag.cc | 10 +++++++++ gtk2_ardour/canvas-flag.h | 3 ++- gtk2_ardour/midi_region_view.cc | 46 +++++++++++++++++++++++++++++++++++++++ gtk2_ardour/midi_region_view.h | 11 ++++++++++ gtk2_ardour/midi_time_axis.cc | 41 ++++++++++++++++++++++++---------- gtk2_ardour/midi_time_axis.h | 2 ++ gtk2_ardour/step_editing.bindings | 2 +- gtk2_ardour/step_entry.cc | 46 +++++++++++++++++++++++++++++++++++---- gtk2_ardour/step_entry.h | 10 +++++++++ libs/ardour/ardour/midi_track.h | 2 +- libs/ardour/midi_track.cc | 2 -- 11 files changed, 155 insertions(+), 20 deletions(-) diff --git a/gtk2_ardour/canvas-flag.cc b/gtk2_ardour/canvas-flag.cc index ad75c28fdf..186790ff1f 100644 --- a/gtk2_ardour/canvas-flag.cc +++ b/gtk2_ardour/canvas-flag.cc @@ -76,3 +76,13 @@ CanvasFlag::on_event(GdkEvent* /*ev*/) */ return false; } + +void +CanvasFlag::set_height (double h) +{ + _height = h; + + if (_line) { + _line->property_y2() = _height; + } +} diff --git a/gtk2_ardour/canvas-flag.h b/gtk2_ardour/canvas-flag.h index 5892358491..ef78221803 100644 --- a/gtk2_ardour/canvas-flag.h +++ b/gtk2_ardour/canvas-flag.h @@ -31,7 +31,8 @@ public: virtual bool on_event(GdkEvent* ev); - void set_text(const std::string& a_text); + virtual void set_text(const std::string& a_text); + virtual void set_height (double); protected: Text* _text; diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index d12b7541f2..40efac102d 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -23,6 +23,7 @@ #include #include +#include #include @@ -87,6 +88,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & , _diff_command(0) , _ghost_note(0) , _drag_rect (0) + , _step_edit_cursor (0) , _mouse_state(None) , _pressed_button(0) , _sort_needed (true) @@ -1101,8 +1103,10 @@ MidiRegionView::~MidiRegionView () _selection.clear(); clear_events(); + delete _note_group; delete _diff_command; + delete _step_edit_cursor; } void @@ -1144,6 +1148,10 @@ MidiRegionView::set_height (double height) if (name_pixbuf) { name_pixbuf->raise_to_top(); } + + for (PgmChanges::iterator x = _pgm_changes.begin(); x != _pgm_changes.end(); ++x) { + (*x)->set_height (midi_stream_view()->contents_height()); + } } @@ -2968,3 +2976,41 @@ MidiRegionView::enable_display (bool yn) redisplay_model (); } } + +void +MidiRegionView::show_step_edit_cursor (Evoral::MusicalTime pos) +{ + if (_step_edit_cursor == 0) { + ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group(); + + _step_edit_cursor = new ArdourCanvas::Pixbuf (*group); + _step_edit_cursor->property_y() = 0; + _step_edit_cursor->property_pixbuf() = ::get_icon ("wholenote"); + } + + move_step_edit_cursor (pos); + _step_edit_cursor->show (); +} + +void +MidiRegionView::move_step_edit_cursor (Evoral::MusicalTime pos) +{ + if (_step_edit_cursor) { + double pixel = trackview.editor().frame_to_pixel (beats_to_frames (pos)); + Glib::RefPtr pb = _step_edit_cursor->property_pixbuf(); + + if (pixel >= (pb->get_width()/2.0)) { + pixel -= pb->get_width()/2.0; + } + + _step_edit_cursor->property_x() = pixel; + } +} + +void +MidiRegionView::hide_step_edit_cursor () +{ + if (_step_edit_cursor) { + _step_edit_cursor->hide (); + } +} diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index 1f77cf3741..f18f3bce02 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -46,6 +46,12 @@ #include "canvas-program-change.h" #include "canvas-sysex.h" +namespace Gnome { + namespace Canvas { + class Pixbuf; + } +}; + namespace ARDOUR { class MidiRegion; class MidiModel; @@ -103,6 +109,10 @@ class MidiRegionView : public RegionView void set_frame_color(); void color_handler (); + + void show_step_edit_cursor (Evoral::MusicalTime pos); + void move_step_edit_cursor (Evoral::MusicalTime pos); + void hide_step_edit_cursor (); void redisplay_model(); @@ -363,6 +373,7 @@ class MidiRegionView : public RegionView double _last_x; double _last_y; ArdourCanvas::SimpleRect* _drag_rect; + ArdourCanvas::Pixbuf* _step_edit_cursor; MouseState _mouse_state; int _pressed_button; diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index 3dada95f84..00b542fd13 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -905,10 +905,16 @@ MidiTimeAxisView::start_step_editing () if (step_edit_region) { RegionView* rv = view()->find_view (step_edit_region); step_edit_region_view = dynamic_cast (rv); + } else { - step_edit_region_view = 0; - } + step_edit_region = add_region (step_edit_insert_position); + RegionView* rv = view()->find_view (step_edit_region); + step_edit_region_view = dynamic_cast(rv); + } + if (step_edit_region_view) { + step_edit_region_view->show_step_edit_cursor (0.0); + } if (step_editor == 0) { step_editor = new StepEntry (*this); @@ -933,6 +939,10 @@ MidiTimeAxisView::stop_step_editing () if (step_editor) { step_editor->hide (); } + + if (step_edit_region_view) { + step_edit_region_view->hide_step_edit_cursor(); + } } void @@ -966,16 +976,20 @@ MidiTimeAxisView::check_step_edit () } int -MidiTimeAxisView::step_add_note (uint8_t channel, uint8_t pitch, uint8_t velocity, Evoral::MusicalTime beat_duration) +MidiTimeAxisView::step_add_bank_change (uint8_t channel, uint8_t bank) { + return 0; +} - if (step_edit_region == 0) { - - step_edit_region = add_region (step_edit_insert_position); - RegionView* rv = view()->find_view (step_edit_region); - step_edit_region_view = dynamic_cast(rv); - } - +int +MidiTimeAxisView::step_add_program_change (uint8_t channel, uint8_t program) +{ + return 0; +} + +int +MidiTimeAxisView::step_add_note (uint8_t channel, uint8_t pitch, uint8_t velocity, Evoral::MusicalTime beat_duration) +{ if (step_edit_region && step_edit_region_view) { if (step_edit_beat_pos < 0.0) { framecnt_t frames_from_start = _editor.get_preferred_edit_position() - step_edit_region->position(); @@ -1024,9 +1038,10 @@ MidiTimeAxisView::step_add_note (uint8_t channel, uint8_t pitch, uint8_t velocit if (!_step_edit_within_chord) { step_edit_beat_pos += beat_duration; + step_edit_region_view->move_step_edit_cursor (step_edit_beat_pos); } else { step_edit_beat_pos += 1.0/Meter::ticks_per_beat; // tiny, but no longer overlapping - _step_edit_chord_duration = beat_duration; + _step_edit_chord_duration = max (_step_edit_chord_duration, beat_duration); } } @@ -1062,6 +1077,7 @@ MidiTimeAxisView::step_edit_toggle_chord () if (_step_edit_within_chord) { _step_edit_within_chord = false; step_edit_beat_pos += _step_edit_chord_duration; + step_edit_region_view->move_step_edit_cursor (step_edit_beat_pos); } else { _step_edit_triplet_countdown = 0; _step_edit_within_chord = true; @@ -1081,6 +1097,7 @@ MidiTimeAxisView::step_edit_rest (Evoral::MusicalTime beats) if (success) { step_edit_beat_pos += beats; + step_edit_region_view->move_step_edit_cursor (step_edit_beat_pos); } } @@ -1088,6 +1105,7 @@ void MidiTimeAxisView::step_edit_beat_sync () { step_edit_beat_pos = ceil (step_edit_beat_pos); + step_edit_region_view->move_step_edit_cursor (step_edit_beat_pos); } void @@ -1101,6 +1119,7 @@ MidiTimeAxisView::step_edit_bar_sync () step_edit_region_view->beats_to_frames (step_edit_beat_pos); fpos = _session->tempo_map().round_to_bar (fpos, 1); step_edit_beat_pos = ceil (step_edit_region_view->frames_to_beats (fpos - step_edit_region->position())); + step_edit_region_view->move_step_edit_cursor (step_edit_beat_pos); } boost::shared_ptr diff --git a/gtk2_ardour/midi_time_axis.h b/gtk2_ardour/midi_time_axis.h index c9983c64ef..caf1a1fc02 100644 --- a/gtk2_ardour/midi_time_axis.h +++ b/gtk2_ardour/midi_time_axis.h @@ -91,6 +91,8 @@ class MidiTimeAxisView : public RouteTimeAxisView void step_edit_rest (Evoral::MusicalTime beats); void step_edit_beat_sync (); void step_edit_bar_sync (); + int step_add_bank_change (uint8_t channel, uint8_t bank); + int step_add_program_change (uint8_t channel, uint8_t program); int step_add_note (uint8_t channel, uint8_t pitch, uint8_t velocity, Evoral::MusicalTime beat_duration); bool step_edit_within_triplet () const; diff --git a/gtk2_ardour/step_editing.bindings b/gtk2_ardour/step_editing.bindings index cd9a9733b2..d7e8df14b1 100644 --- a/gtk2_ardour/step_editing.bindings +++ b/gtk2_ardour/step_editing.bindings @@ -1,5 +1,5 @@ - + diff --git a/gtk2_ardour/step_entry.cc b/gtk2_ardour/step_entry.cc index c9e8bf7e58..fa5a3aac85 100644 --- a/gtk2_ardour/step_entry.cc +++ b/gtk2_ardour/step_entry.cc @@ -73,6 +73,12 @@ StepEntry::StepEntry (MidiTimeAxisView& mtv) , length_divisor_spinner (length_divisor_adjustment) , velocity_adjustment (64.0, 0.0, 127.0, 1.0, 4.0) , velocity_spinner (velocity_adjustment) + , bank_adjustment (0, 0.0, 127.0, 1.0, 4.0) + , bank_spinner (bank_adjustment) + , bank_button (_("+")) + , program_adjustment (0, 0.0, 127.0, 1.0, 4.0) + , program_spinner (program_adjustment) + , program_button (_("+")) , _piano (0) , piano (0) , _mtv (&mtv) @@ -287,11 +293,11 @@ StepEntry::StepEntry (MidiTimeAxisView& mtv) w->show(); chord_button.add (*w); - rest_box.pack_start (rest_button, false, false); - rest_box.pack_start (grid_rest_button, false, false); + rest_box.pack_start (rest_button, true, false); + rest_box.pack_start (grid_rest_button, true, false); - resync_box.pack_start (beat_resync_button, false, false); - resync_box.pack_start (bar_resync_button, false, false); + resync_box.pack_start (beat_resync_button, true, false); + resync_box.pack_start (bar_resync_button, true, false); ARDOUR_UI::instance()->set_tip (&chord_button, _("Stack inserted notes to form a chord"), ""); ARDOUR_UI::instance()->set_tip (&sustain_button, _("Extend selected notes by note length"), ""); @@ -300,6 +306,8 @@ StepEntry::StepEntry (MidiTimeAxisView& mtv) ARDOUR_UI::instance()->set_tip (&grid_rest_button, _("Insert a grid-unit's rest"), ""); ARDOUR_UI::instance()->set_tip (&beat_resync_button, _("Insert a rest until the next beat"), ""); ARDOUR_UI::instance()->set_tip (&bar_resync_button, _("Insert a rest until the next bar"), ""); + ARDOUR_UI::instance()->set_tip (&bank_button, _("Insert a bank change message"), ""); + ARDOUR_UI::instance()->set_tip (&program_button, _("Insert a program change message"), ""); upper_box.set_spacing (6); upper_box.pack_start (chord_button, false, false); @@ -341,6 +349,22 @@ StepEntry::StepEntry (MidiTimeAxisView& mtv) v->pack_start (octave_spinner, false, false); upper_box.pack_start (*v, false, false); + v = manage (new VBox); + l = manage (new Label (_("Bank"))); + v->set_spacing (6); + v->pack_start (*l, false, false); + v->pack_start (bank_spinner, false, false); + v->pack_start (bank_button, false, false); + upper_box.pack_start (*v, false, false); + + v = manage (new VBox); + l = manage (new Label (_("Program"))); + v->set_spacing (6); + v->pack_start (*l, false, false); + v->pack_start (program_spinner, false, false); + v->pack_start (program_button, false, false); + upper_box.pack_start (*v, false, false); + velocity_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::velocity_value_change)); length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_value_change)); @@ -352,6 +376,8 @@ StepEntry::StepEntry (MidiTimeAxisView& mtv) g_signal_connect(G_OBJECT(_piano), "note-off", G_CALLBACK(_note_off_event_handler), this); g_signal_connect(G_OBJECT(_piano), "rest", G_CALLBACK(_rest_event_handler), this); + program_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::program_click)); + bank_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bank_click)); rest_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::rest_click)); grid_rest_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::grid_rest_click)); chord_button.signal_toggled().connect (sigc::mem_fun (*this, &StepEntry::chord_toggled)); @@ -566,6 +592,18 @@ StepEntry::load_bindings () } } +void +StepEntry::program_click () +{ + _mtv->step_add_program_change (note_channel(), (int8_t) floor (program_adjustment.get_value())); +} + +void +StepEntry::bank_click () +{ + _mtv->step_add_bank_change (note_channel(), (int8_t) floor (bank_adjustment.get_value())); +} + void StepEntry::insert_rest () { diff --git a/gtk2_ardour/step_entry.h b/gtk2_ardour/step_entry.h index d9c5492304..0fd7d6f121 100644 --- a/gtk2_ardour/step_entry.h +++ b/gtk2_ardour/step_entry.h @@ -100,6 +100,14 @@ class StepEntry : public ArdourDialog Gtk::Adjustment velocity_adjustment; Gtk::SpinButton velocity_spinner; + Gtk::Adjustment bank_adjustment; + Gtk::SpinButton bank_spinner; + Gtk::Button bank_button; + + Gtk::Adjustment program_adjustment; + Gtk::SpinButton program_spinner; + Gtk::Button program_button; + void length_changed (); void velocity_changed (); void velocity_value_change (); @@ -109,6 +117,8 @@ class StepEntry : public ArdourDialog Gtk::Widget* piano; MidiTimeAxisView* _mtv; + void bank_click (); + void program_click (); void rest_click (); void grid_rest_click (); void sustain_click (); diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h index 6236667650..7e0525608d 100644 --- a/libs/ardour/ardour/midi_track.h +++ b/libs/ardour/ardour/midi_track.h @@ -84,7 +84,7 @@ public: void set_step_editing (bool yn); MidiRingBuffer& step_edit_ring_buffer() { return _step_edit_ring_buffer; } - static PBD::Signal1 StepEditStatusChange; + PBD::Signal1 StepEditStatusChange; uint8_t default_channel() const { return _default_channel; } void set_default_channel (uint8_t chn); diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 83e42800be..780243f18b 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -49,8 +49,6 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -PBD::Signal1 MidiTrack::StepEditStatusChange; - MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mode) : Track (sess, name, flag, mode, DataType::MIDI) , _immediate_events(1024) // FIXME: size? -- cgit v1.2.3