summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-08-11 18:21:37 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-08-11 18:21:37 +0000
commit5182f0770cca50cbb7c8fe419b2e64af02525553 (patch)
treed83afeadcc8ab51bcdae2cb993f2f8a60100e9c2
parentfd3219bf29415006d6680fc5cf2dac97c35972bc (diff)
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
-rw-r--r--gtk2_ardour/canvas-flag.cc10
-rw-r--r--gtk2_ardour/canvas-flag.h3
-rw-r--r--gtk2_ardour/midi_region_view.cc46
-rw-r--r--gtk2_ardour/midi_region_view.h11
-rw-r--r--gtk2_ardour/midi_time_axis.cc41
-rw-r--r--gtk2_ardour/midi_time_axis.h2
-rw-r--r--gtk2_ardour/step_editing.bindings2
-rw-r--r--gtk2_ardour/step_entry.cc46
-rw-r--r--gtk2_ardour/step_entry.h10
-rw-r--r--libs/ardour/ardour/midi_track.h2
-rw-r--r--libs/ardour/midi_track.cc2
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 <ostream>
#include <gtkmm.h>
+#include <libgnomecanvasmm/pixbuf.h>
#include <gtkmm2ext/gtk_ui.h>
@@ -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<Gdk::Pixbuf> 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<MidiRegionView*> (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<MidiRegionView*>(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<MidiRegionView*>(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<Region>
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 @@
<?xml version="1.0" encoding="UTF-8"?>
-<Bindings>
+<Bindings name="qwerty">
<Press>
<Binding key="a" action="StepEditing/insert-a"/>
<Binding key="Primary-a" action="StepEditing/insert-b"/>
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));
@@ -567,6 +593,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 ()
{
_mtv->step_edit_rest (note_length());
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<nframes_t>& step_edit_ring_buffer() { return _step_edit_ring_buffer; }
- static PBD::Signal1<void,bool> StepEditStatusChange;
+ PBD::Signal1<void,bool> 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<void,bool> 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?