summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/audio_time_axis.cc19
-rw-r--r--gtk2_ardour/audio_time_axis.h1
-rw-r--r--gtk2_ardour/editing_syms.h1
-rw-r--r--gtk2_ardour/editor.cc12
-rw-r--r--gtk2_ardour/editor.h2
-rw-r--r--gtk2_ardour/editor_actions.cc1
-rw-r--r--gtk2_ardour/editor_mouse.cc16
-rw-r--r--gtk2_ardour/midi_region_view.cc114
-rw-r--r--gtk2_ardour/midi_region_view.h4
-rw-r--r--gtk2_ardour/midi_streamview.cc27
-rw-r--r--gtk2_ardour/midi_streamview.h19
-rw-r--r--gtk2_ardour/midi_time_axis.cc37
-rw-r--r--gtk2_ardour/midi_time_axis.h5
-rw-r--r--gtk2_ardour/route_time_axis.cc30
-rw-r--r--gtk2_ardour/route_time_axis.h1
15 files changed, 243 insertions, 46 deletions
diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc
index db88982089..437e037836 100644
--- a/gtk2_ardour/audio_time_axis.cc
+++ b/gtk2_ardour/audio_time_axis.cc
@@ -206,17 +206,6 @@ AudioTimeAxisView::append_extra_display_menu_items ()
items.push_back (MenuElem (_("Waveform"), *waveform_menu));
-
- Menu *layers_menu = manage(new Menu);
- MenuList &layers_items = layers_menu->items();
- layers_menu->set_name("ArdourContextMenu");
-
- RadioMenuItem::Group layers_group;
-
- layers_items.push_back(RadioMenuElem (layers_group, _("Overlaid"), bind (mem_fun (*this, &AudioTimeAxisView::set_layer_display), Overlaid)));
- layers_items.push_back(RadioMenuElem (layers_group, _("Stacked"), bind (mem_fun (*this, &AudioTimeAxisView::set_layer_display), Stacked)));
-
- items.push_back (MenuElem (_("Layers"), *layers_menu));
}
Gtk::Menu*
@@ -487,11 +476,3 @@ AudioTimeAxisView::update_control_names ()
}
}
-void
-AudioTimeAxisView::set_layer_display (LayerDisplay d)
-{
- AudioStreamView* asv = audio_view ();
- if (asv) {
- asv->set_layer_display (d);
- }
-}
diff --git a/gtk2_ardour/audio_time_axis.h b/gtk2_ardour/audio_time_axis.h
index 822fbcadf0..a65bca1a70 100644
--- a/gtk2_ardour/audio_time_axis.h
+++ b/gtk2_ardour/audio_time_axis.h
@@ -76,7 +76,6 @@ class AudioTimeAxisView : public RouteTimeAxisView
void hide_all_xfades ();
void hide_dependent_views (TimeAxisViewItem&);
void reveal_dependent_views (TimeAxisViewItem&);
- void set_layer_display (LayerDisplay d);
/* Overridden from parent to store display state */
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
diff --git a/gtk2_ardour/editing_syms.h b/gtk2_ardour/editing_syms.h
index f415e2c49c..7ae45c4c06 100644
--- a/gtk2_ardour/editing_syms.h
+++ b/gtk2_ardour/editing_syms.h
@@ -60,6 +60,7 @@ MOUSEMODE(MouseRange)
MOUSEMODE(MouseTimeFX)
MOUSEMODE(MouseZoom)
MOUSEMODE(MouseAudition)
+MOUSEMODE(MouseNote)
/* Changing this order will break the menu */
ZOOMFOCUS(ZoomFocusLeft)
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index a771fb51b4..cd1b9e4b7c 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -152,6 +152,7 @@ Gdk::Cursor* Editor::zoom_cursor = 0;
Gdk::Cursor* Editor::time_fx_cursor = 0;
Gdk::Cursor* Editor::fader_cursor = 0;
Gdk::Cursor* Editor::speaker_cursor = 0;
+Gdk::Cursor* Editor::note_cursor = 0;
Gdk::Cursor* Editor::wait_cursor = 0;
Gdk::Cursor* Editor::timebar_cursor = 0;
@@ -1210,7 +1211,7 @@ Editor::build_cursors ()
mask = Bitmap::create (speaker_cursor_mask_bits, speaker_cursor_width, speaker_cursor_height);
speaker_cursor = new Gdk::Cursor (source, mask, ffg, fbg, speaker_cursor_x_hot, speaker_cursor_y_hot);
}
-
+
grabber_cursor = new Gdk::Cursor (HAND2);
cross_hair_cursor = new Gdk::Cursor (CROSSHAIR);
trimmer_cursor = new Gdk::Cursor (SB_H_DOUBLE_ARROW);
@@ -1218,6 +1219,7 @@ Editor::build_cursors ()
time_fx_cursor = new Gdk::Cursor (SIZING);
wait_cursor = new Gdk::Cursor (WATCH);
timebar_cursor = new Gdk::Cursor(LEFT_PTR);
+ note_cursor = new Gdk::Cursor (PENCIL);
}
/** Pop up a context menu for when the user clicks on a fade in or fade out */
@@ -2322,6 +2324,9 @@ Editor::setup_toolbar ()
mouse_mode_buttons.push_back (&mouse_timefx_button);
mouse_audition_button.add (*(manage (new Image (::get_icon("tool_audition")))));
mouse_audition_button.set_relief(Gtk::RELIEF_NONE);
+ mouse_note_button.add (*(manage (new Image (::get_icon("tool_note")))));
+ mouse_note_button.set_relief(Gtk::RELIEF_NONE);
+ mouse_mode_buttons.push_back (&mouse_note_button);
mouse_mode_buttons.push_back (&mouse_audition_button);
mouse_mode_button_set = new GroupedButtons (mouse_mode_buttons);
@@ -2336,6 +2341,7 @@ Editor::setup_toolbar ()
mouse_mode_button_box.pack_start(mouse_gain_button, true, true);
mouse_mode_button_box.pack_start(mouse_timefx_button, true, true);
mouse_mode_button_box.pack_start(mouse_audition_button, true, true);
+ mouse_mode_button_box.pack_start(mouse_note_button, true, true);
mouse_mode_button_box.set_homogeneous(true);
vector<string> edit_mode_strings;
@@ -2368,6 +2374,7 @@ Editor::setup_toolbar ()
mouse_zoom_button.set_name ("MouseModeButton");
mouse_timefx_button.set_name ("MouseModeButton");
mouse_audition_button.set_name ("MouseModeButton");
+ mouse_note_button.set_name ("MouseModeButton");
ARDOUR_UI::instance()->tooltips().set_tip (mouse_move_button, _("Select/Move Objects"));
ARDOUR_UI::instance()->tooltips().set_tip (mouse_select_button, _("Select/Move Ranges"));
@@ -2375,6 +2382,7 @@ Editor::setup_toolbar ()
ARDOUR_UI::instance()->tooltips().set_tip (mouse_zoom_button, _("Select Zoom Range"));
ARDOUR_UI::instance()->tooltips().set_tip (mouse_timefx_button, _("Stretch/Shrink Regions"));
ARDOUR_UI::instance()->tooltips().set_tip (mouse_audition_button, _("Listen to Specific Regions"));
+ ARDOUR_UI::instance()->tooltips().set_tip (mouse_note_button, _("Edit MIDI Notes"));
mouse_move_button.unset_flags (CAN_FOCUS);
mouse_select_button.unset_flags (CAN_FOCUS);
@@ -2382,6 +2390,7 @@ Editor::setup_toolbar ()
mouse_zoom_button.unset_flags (CAN_FOCUS);
mouse_timefx_button.unset_flags (CAN_FOCUS);
mouse_audition_button.unset_flags (CAN_FOCUS);
+ mouse_note_button.unset_flags (CAN_FOCUS);
mouse_select_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseRange));
mouse_select_button.signal_button_release_event().connect (mem_fun(*this, &Editor::mouse_select_button_release));
@@ -2391,6 +2400,7 @@ Editor::setup_toolbar ()
mouse_zoom_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseZoom));
mouse_timefx_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseTimeFX));
mouse_audition_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseAudition));
+ mouse_note_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseNote));
// mouse_move_button.set_active (true);
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index b9a4f29cec..b4c0a03f85 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -808,6 +808,7 @@ class Editor : public PublicEditor
static Gdk::Cursor* time_fx_cursor;
static Gdk::Cursor* fader_cursor;
static Gdk::Cursor* speaker_cursor;
+ static Gdk::Cursor* note_cursor;
static Gdk::Cursor* wait_cursor;
static Gdk::Cursor* timebar_cursor;
@@ -1317,6 +1318,7 @@ class Editor : public PublicEditor
Gtk::ToggleButton mouse_zoom_button;
Gtk::ToggleButton mouse_timefx_button;
Gtk::ToggleButton mouse_audition_button;
+ Gtk::ToggleButton mouse_note_button;
GroupedButtons *mouse_mode_button_set;
void mouse_mode_toggled (Editing::MouseMode m);
bool ignore_mouse_mode_toggle;
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 52f30e7d5d..585c4669e2 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -301,6 +301,7 @@ Editor::register_actions ()
ActionManager::register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-gain", _("Gain Tool"), bind (mem_fun(*this, &Editor::set_mouse_mode), Editing::MouseGain, false));
ActionManager::register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-zoom", _("Zoom Tool"), bind (mem_fun(*this, &Editor::set_mouse_mode), Editing::MouseZoom, false));
ActionManager::register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-timefx", _("Timefx Tool"), bind (mem_fun(*this, &Editor::set_mouse_mode), Editing::MouseTimeFX, false));
+ ActionManager::register_radio_action (mouse_mode_actions, mouse_mode_group, "set-mouse-mode-note", _("Note Tool"), bind (mem_fun(*this, &Editor::set_mouse_mode), Editing::MouseNote, false));
ActionManager::register_action (editor_actions, X_("SnapTo"), _("Snap To"));
ActionManager::register_action (editor_actions, X_("SnapMode"), _("Snap Mode"));
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 406eda01db..be2d0bc47d 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -160,6 +160,12 @@ Editor::mouse_mode_toggled (MouseMode m)
set_mouse_mode (m);
}
break;
+
+ case MouseNote:
+ if (mouse_note_button.get_active()) {
+ set_mouse_mode (m);
+ }
+ break;
default:
break;
@@ -244,6 +250,11 @@ Editor::set_mouse_mode (MouseMode m, bool force)
mouse_audition_button.set_active (true);
current_canvas_cursor = speaker_cursor;
break;
+
+ case MouseNote:
+ mouse_note_button.set_active (true);
+ current_canvas_cursor = note_cursor;
+ break;
}
ignore_mouse_mode_toggle = false;
@@ -286,6 +297,11 @@ Editor::step_mouse_mode (bool next)
if (next) set_mouse_mode (MouseObject);
else set_mouse_mode (MouseTimeFX);
break;
+
+ case MouseNote:
+ if (next) set_mouse_mode (MouseObject);
+ else set_mouse_mode (MouseAudition);
+ break;
}
}
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index e4cb80bca0..81ea4029de 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -25,10 +25,12 @@
#include <gtkmm2ext/gtk_ui.h>
#include <ardour/playlist.h>
+#include <ardour/tempo.h>
#include <ardour/midi_region.h>
#include <ardour/midi_source.h>
#include <ardour/midi_diskstream.h>
#include <ardour/midi_events.h>
+#include <ardour/midi_model.h>
#include "streamview.h"
#include "midi_region_view.h"
@@ -93,6 +95,52 @@ MidiRegionView::init (Gdk::Color& basic_color, bool wfd)
midi_region()->midi_source(0)->load_model();
display_events();
}
+
+ group->signal_event().connect (mem_fun (this, &MidiRegionView::canvas_event));
+}
+
+bool
+MidiRegionView::canvas_event(GdkEvent* ev)
+{
+ if (trackview.editor.current_mouse_mode() == MouseNote) {
+ if (ev->type == GDK_BUTTON_PRESS) {
+ MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
+ MidiStreamView* const view = mtv->midi_view();
+
+ const uint8_t note_range = view->highest_note() - view->lowest_note() + 1;
+ const double footer_height = name_highlight->property_y2() - name_highlight->property_y1();
+ const double roll_height = trackview.height - footer_height;
+
+ double x = ev->button.x;
+ double y = ev->button.y;
+ get_canvas_group()->w2i(x, y);
+
+ double note = floor((roll_height - y) / roll_height * (double)note_range) + view->lowest_note();
+ assert(note >= 0.0);
+ assert(note <= 127.0);
+
+ const nframes_t stamp = trackview.editor.pixel_to_frame (x);
+ assert(stamp >= 0);
+ //assert(stamp <= _region->length());
+
+ const Meter& m = trackview.session().tempo_map().meter_at(stamp);
+ const Tempo& t = trackview.session().tempo_map().tempo_at(stamp);
+ double dur = m.frames_per_bar(t, trackview.session().frame_rate()) / m.beats_per_bar();
+
+ // Add a 1 beat long note (for now)
+ const MidiModel::Note new_note(stamp, dur, (uint8_t)note, 0x40);
+
+ MidiModel::Notes& notes = midi_region()->midi_source(0)->model()->notes();
+ MidiModel::Notes::iterator i = upper_bound(notes.begin(), notes.end(), new_note,
+ MidiModel::NoteTimeComparator());
+ notes.insert(i, new_note);
+ view->update_bounds(new_note.note);
+
+ add_note(new_note);
+ }
+ }
+
+ return false;
}
@@ -113,8 +161,8 @@ MidiRegionView::display_events()
begin_write();
- for (size_t i=0; i < midi_region()->midi_source(0)->model()->n_events(); ++i)
- add_event(midi_region()->midi_source(0)->model()->event_at(i));
+ for (size_t i=0; i < midi_region()->midi_source(0)->model()->n_notes(); ++i)
+ add_note(midi_region()->midi_source(0)->model()->note_at(i));
end_write();
}
@@ -222,6 +270,11 @@ MidiRegionView::end_write()
}
+/** Add a MIDI event.
+ *
+ * This is used while recording, and handles displaying still-unresolved notes.
+ * Displaying an existing model is simpler, and done with add_note.
+ */
void
MidiRegionView::add_event (const MidiEvent& ev)
{
@@ -300,4 +353,61 @@ MidiRegionView::extend_active_notes()
}
+/** Add a MIDI note (with duration).
+ *
+ * This does no 'realtime' note resolution, notes from a MidiModel have a
+ * duration so they can be drawn in full immediately.
+ */
+void
+MidiRegionView::add_note (const MidiModel::Note& note)
+{
+ assert(note.start >= 0);
+ assert(note.start < _region->length());
+ //assert(note.start + note.duration < _region->length());
+
+ /*printf("Event, time = %f, size = %zu, data = ", ev.time, ev.size);
+ for (size_t i=0; i < ev.size; ++i) {
+ printf("%X ", ev.buffer[i]);
+ }
+ printf("\n\n");*/
+
+ MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
+ MidiStreamView* const view = mtv->midi_view();
+ ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group();
+
+ const uint8_t note_range = view->highest_note() - view->lowest_note() + 1;
+ const double footer_height = name_highlight->property_y2() - name_highlight->property_y1();
+ const double pixel_range = (trackview.height - footer_height - 5.0) / (double)note_range;
+
+ if (mtv->note_mode() == Note) {
+ const double y1 = trackview.height - (pixel_range * (note.note - view->lowest_note() + 1))
+ - footer_height - 3.0;
+
+ ArdourCanvas::SimpleRect * ev_rect = new Gnome::Canvas::SimpleRect(*group);
+ ev_rect->property_x1() = trackview.editor.frame_to_pixel((nframes_t)note.start);
+ ev_rect->property_y1() = y1;
+ ev_rect->property_x2() = trackview.editor.frame_to_pixel((nframes_t)(note.start + note.duration));
+ ev_rect->property_y2() = y1 + ceil(pixel_range);
+
+ ev_rect->property_fill_color_rgba() = 0xFFFFFF66;
+ ev_rect->property_outline_color_rgba() = 0xFFFFFFAA;
+ ev_rect->property_outline_what() = (guint32) 0xF; // all edges
+
+ ev_rect->show();
+ _events.push_back(ev_rect);
+
+ } else if (mtv->note_mode() == Percussion) {
+ const double x = trackview.editor.frame_to_pixel((nframes_t)note.start);
+ const double y = trackview.height - (pixel_range * (note.note - view->lowest_note() + 1))
+ - footer_height - 3.0;
+
+ Diamond* ev_diamond = new Diamond(*group, std::min(pixel_range, 5.0));
+ ev_diamond->move(x, y);
+ ev_diamond->show();
+ ev_diamond->property_outline_color_rgba() = 0xFFFFFFDD;
+ ev_diamond->property_fill_color_rgba() = 0xFFFFFF66;
+ _events.push_back(ev_diamond);
+ }
+}
+
diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h
index 88ef43243b..6e37da9f50 100644
--- a/gtk2_ardour/midi_region_view.h
+++ b/gtk2_ardour/midi_region_view.h
@@ -25,6 +25,7 @@
#include <libgnomecanvasmm/polygon.h>
#include <sigc++/signal.h>
#include <ardour/midi_region.h>
+#include <ardour/midi_model.h>
#include <ardour/types.h>
#include "region_view.h"
@@ -64,6 +65,7 @@ class MidiRegionView : public RegionView
GhostRegion* add_ghost (AutomationTimeAxisView&);
void add_event(const ARDOUR::MidiEvent& ev);
+ void add_note(const ARDOUR::MidiModel::Note& note);
void begin_write();
void end_write();
@@ -95,6 +97,8 @@ class MidiRegionView : public RegionView
void display_events();
void clear_events();
+ bool canvas_event(GdkEvent* ev);
+
std::vector<ArdourCanvas::Item*> _events;
ArdourCanvas::SimpleRect** _active_notes;
};
diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc
index 862e554cae..30700c8e94 100644
--- a/gtk2_ardour/midi_streamview.cc
+++ b/gtk2_ardour/midi_streamview.cc
@@ -54,8 +54,8 @@ using namespace Editing;
MidiStreamView::MidiStreamView (MidiTimeAxisView& tv)
: StreamView (tv)
- , _lowest_note(0)
- , _highest_note(127)
+ , _lowest_note(60)
+ , _highest_note(60)
{
if (tv.is_track())
stream_base_color = ARDOUR_UI::config()->canvasvar_MidiTrackBase.get();
@@ -137,17 +137,13 @@ MidiStreamView::display_region(MidiRegionView* region_view, bool redisplay_event
boost::shared_ptr<MidiSource> source(region_view->midi_region()->midi_source(0));
- for (size_t i=0; i < source->model()->n_events(); ++i) {
- const MidiEvent& ev = source->model()->event_at(i);
+ for (size_t i=0; i < source->model()->n_notes(); ++i) {
+ const MidiModel::Note& note = source->model()->note_at(i);
- // Look at all note on events to find our note range
- if ((ev.buffer[0] & 0xF0) == MIDI_CMD_NOTE_ON) {
- _lowest_note = min(_lowest_note, ev.buffer[1]);
- _highest_note = max(_highest_note, ev.buffer[1]);
- }
+ update_bounds(note.note);
if (redisplay_events)
- region_view->add_event(ev);
+ region_view->add_note(note);
}
if (redisplay_events)
@@ -164,8 +160,8 @@ MidiStreamView::redisplay_diskstream ()
(*i)->set_valid (false);
}
- _lowest_note = 60; // middle C
- _highest_note = _lowest_note + 11;
+ //_lowest_note = 60; // middle C
+ //_highest_note = _lowest_note + 11;
if (_trackview.is_midi_track()) {
_trackview.get_diskstream()->playlist()->foreach_region (static_cast<StreamView*>(this), &StreamView::add_region_view);
@@ -191,6 +187,13 @@ MidiStreamView::redisplay_diskstream ()
region_layered (*i);
}
}
+
+void
+MidiStreamView::update_bounds(uint8_t note_num)
+{
+ _lowest_note = min(_lowest_note, note_num);
+ _highest_note = max(_highest_note, note_num);
+}
void
diff --git a/gtk2_ardour/midi_streamview.h b/gtk2_ardour/midi_streamview.h
index ce459e2fad..b8ae33cf46 100644
--- a/gtk2_ardour/midi_streamview.h
+++ b/gtk2_ardour/midi_streamview.h
@@ -58,8 +58,18 @@ class MidiStreamView : public StreamView
void get_selectables (jack_nframes_t start, jack_nframes_t end, list<Selectable* >&);
void get_inverted_selectables (Selection&, list<Selectable* >& results);
- uint8_t lowest_note() const { return _lowest_note; }
- uint8_t highest_note() const { return _highest_note; }
+ enum VisibleNoteRange {
+ FullRange,
+ ContentsRange
+ };
+
+ VisibleNoteRange note_range() { return _range; }
+ void set_note_range(VisibleNoteRange r) { _range = r; }
+
+ uint8_t lowest_note() const { return (_range == FullRange) ? 0 : _lowest_note; }
+ uint8_t highest_note() const { return (_range == FullRange) ? 127 : _highest_note; }
+
+ void update_bounds(uint8_t note_num);
void redisplay_diskstream ();
@@ -73,8 +83,9 @@ class MidiStreamView : public StreamView
void color_handler ();
- uint8_t _lowest_note;
- uint8_t _highest_note;
+ VisibleNoteRange _range;
+ uint8_t _lowest_note;
+ uint8_t _highest_note;
};
#endif /* __ardour_midi_streamview_h__ */
diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc
index 48aa78dc06..fb3d67913d 100644
--- a/gtk2_ardour/midi_time_axis.cc
+++ b/gtk2_ardour/midi_time_axis.cc
@@ -157,6 +157,31 @@ MidiTimeAxisView::hide ()
}
void
+MidiTimeAxisView::append_extra_display_menu_items ()
+{
+ using namespace Menu_Helpers;
+
+ MenuList& items = display_menu->items();
+
+ // Note range
+ Menu *range_menu = manage(new Menu);
+ MenuList& range_items = range_menu->items();
+ range_menu->set_name ("ArdourContextMenu");
+
+ RadioMenuItem::Group range_group;
+
+ range_items.push_back (RadioMenuElem (range_group, _("Show Full Range"), bind (
+ mem_fun(*this, &MidiTimeAxisView::set_note_range),
+ MidiStreamView::FullRange)));
+
+ range_items.push_back (RadioMenuElem (range_group, _("Fit Contents"), bind (
+ mem_fun(*this, &MidiTimeAxisView::set_note_range),
+ MidiStreamView::ContentsRange)));
+
+ items.push_back (MenuElem (_("Note range"), *range_menu));
+}
+
+void
MidiTimeAxisView::build_automation_action_menu ()
{
using namespace Menu_Helpers;
@@ -204,6 +229,17 @@ MidiTimeAxisView::set_note_mode(NoteMode mode)
}
}
+
+void
+MidiTimeAxisView::set_note_range(MidiStreamView::VisibleNoteRange range)
+{
+ //if (midi_view()->note_range() != range) {
+ midi_view()->set_note_range(range);
+ midi_view()->redisplay_diskstream();
+ //}
+}
+
+
/** Prompt for a controller with a dialog and add an automation track for it
*/
void
@@ -285,3 +321,4 @@ MidiTimeAxisView::route_active_changed ()
}
}
+
diff --git a/gtk2_ardour/midi_time_axis.h b/gtk2_ardour/midi_time_axis.h
index 039affd979..a35a332e01 100644
--- a/gtk2_ardour/midi_time_axis.h
+++ b/gtk2_ardour/midi_time_axis.h
@@ -38,6 +38,7 @@
#include "enums.h"
#include "route_time_axis.h"
#include "canvas.h"
+#include "midi_streamview.h"
namespace ARDOUR {
class Session;
@@ -67,13 +68,15 @@ class MidiTimeAxisView : public RouteTimeAxisView
void create_automation_child (ARDOUR::Parameter param, bool show);
ARDOUR::NoteMode note_mode() const { return _note_mode; }
-
+
private:
+ void append_extra_display_menu_items ();
void build_automation_action_menu ();
Gtk::Menu* build_mode_menu();
void set_note_mode(ARDOUR::NoteMode mode);
+ void set_note_range(MidiStreamView::VisibleNoteRange range);
void route_active_changed ();
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index e0d93bd41a..dbfb8b029b 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -500,29 +500,42 @@ RouteTimeAxisView::build_display_menu ()
if (is_track()) {
+ Menu *layers_menu = manage(new Menu);
+ MenuList &layers_items = layers_menu->items();
+ layers_menu->set_name("ArdourContextMenu");
+
+ RadioMenuItem::Group layers_group;
+
+ layers_items.push_back(RadioMenuElem (layers_group, _("Overlaid"),
+ bind (mem_fun (*this, &RouteTimeAxisView::set_layer_display), Overlaid)));
+ layers_items.push_back(RadioMenuElem (layers_group, _("Stacked"),
+ bind (mem_fun (*this, &RouteTimeAxisView::set_layer_display), Stacked)));
+
+ items.push_back (MenuElem (_("Layers"), *layers_menu));
+
Menu* alignment_menu = manage (new Menu);
MenuList& alignment_items = alignment_menu->items();
alignment_menu->set_name ("ArdourContextMenu");
RadioMenuItem::Group align_group;
-
+
alignment_items.push_back (RadioMenuElem (align_group, _("Align with existing material"),
- bind (mem_fun(*this, &RouteTimeAxisView::set_align_style), ExistingMaterial)));
+ bind (mem_fun(*this, &RouteTimeAxisView::set_align_style), ExistingMaterial)));
align_existing_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back());
if (get_diskstream()->alignment_style() == ExistingMaterial)
align_existing_item->set_active();
-
+
alignment_items.push_back (RadioMenuElem (align_group, _("Align with capture time"),
- bind (mem_fun(*this, &RouteTimeAxisView::set_align_style), CaptureTime)));
+ bind (mem_fun(*this, &RouteTimeAxisView::set_align_style), CaptureTime)));
align_capture_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back());
if (get_diskstream()->alignment_style() == CaptureTime)
align_capture_item->set_active();
-
+
items.push_back (MenuElem (_("Alignment"), *alignment_menu));
get_diskstream()->AlignmentStyleChanged.connect (
mem_fun(*this, &RouteTimeAxisView::align_style_changed));
-
+
mode_menu = build_mode_menu();
if (mode_menu)
items.push_back (MenuElem (_("Mode"), *mode_menu));
@@ -1980,3 +1993,8 @@ RouteTimeAxisView::update_rec_display ()
name_entry.set_sensitive (!_route->record_enabled());
}
+void
+RouteTimeAxisView::set_layer_display (LayerDisplay d)
+{
+ _view->set_layer_display (d);
+}
diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h
index 0d42f331a9..cd92f47322 100644
--- a/gtk2_ardour/route_time_axis.h
+++ b/gtk2_ardour/route_time_axis.h
@@ -79,6 +79,7 @@ public:
void get_selectables (nframes_t start, nframes_t end, double top, double bot, list<Selectable *>&);
void get_inverted_selectables (Selection&, list<Selectable*>&);
bool show_automation(ARDOUR::Parameter param);
+ void set_layer_display (LayerDisplay d);
boost::shared_ptr<ARDOUR::Region> find_next_region (nframes_t pos, ARDOUR::RegionPoint, int32_t dir);