X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fmidi_time_axis.cc;h=21848fff59de2e99d1fa8e59a6680833aeefccbf;hb=29f0d9732eb68fcaa22219cedddddd47bcaa8c17;hp=081fc543db5d734d1628c66905e218302ee65672;hpb=60454cc8dc1ca5e1819b853b55916d52497d495c;p=ardour.git diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index 081fc543db..21848fff59 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include #include @@ -48,6 +48,8 @@ #include "ardour_ui.h" #include "midi_time_axis.h" #include "automation_time_axis.h" +#include "automation_line.h" +#include "add_midi_cc_track_dialog.h" #include "canvas_impl.h" #include "crossfade_view.h" #include "enums.h" @@ -59,9 +61,7 @@ #include "point_selection.h" #include "prompter.h" #include "public_editor.h" -#include "redirect_automation_line.h" -#include "redirect_automation_time_axis.h" -#include "regionview.h" +#include "region_view.h" #include "rgb_macros.h" #include "selection.h" #include "simplerect.h" @@ -78,9 +78,12 @@ using namespace Gtk; using namespace Editing; -MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session& sess, Route& rt, Canvas& canvas) - : AxisView(sess), // FIXME: won't compile without this, why?? - RouteTimeAxisView(ed, sess, rt, canvas) +MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session& sess, boost::shared_ptr rt, Canvas& canvas) + : AxisView(sess) // FIXME: won't compile without this, why?? + , RouteTimeAxisView(ed, sess, rt, canvas) + , _note_mode(Sustained) + , _note_mode_item(NULL) + , _percussion_mode_item(NULL) { subplugin_menu.set_name ("ArdourContextMenu"); @@ -91,36 +94,32 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session& sess, Route& rt, mute_button->set_active (false); solo_button->set_active (false); - if (is_midi_track()) + if (is_midi_track()) { controls_ebox.set_name ("MidiTimeAxisViewControlsBaseUnselected"); - else // bus + _note_mode = midi_track()->note_mode(); + } else { // MIDI bus (which doesn't exist yet..) controls_ebox.set_name ("MidiBusControlsBaseUnselected"); + } /* map current state of the route */ - //redirects_changed (0); + processors_changed (); ensure_xml_node (); set_state (*xml_node); - //_route.redirects_changed.connect (mem_fun(*this, &MidiTimeAxisView::redirects_changed)); + _route->processors_changed.connect (mem_fun(*this, &MidiTimeAxisView::processors_changed)); - if (is_midi_track()) { + if (is_track()) { controls_ebox.set_name ("MidiTrackControlsBaseUnselected"); controls_base_selected_name = "MidiTrackControlsBaseSelected"; controls_base_unselected_name = "MidiTrackControlsBaseUnselected"; /* ask for notifications of any new RegionViews */ - //view->MidiRegionViewAdded.connect (mem_fun(*this, &MidiTimeAxisView::region_view_added)); - //view->attach (); + _view->attach (); - } else { /* bus */ - - controls_ebox.set_name ("MidiBusControlsBaseUnselected"); - controls_base_selected_name = "MidiBusControlsBaseSelected"; - controls_base_unselected_name = "MidiBusControlsBaseUnselected"; } } @@ -128,6 +127,12 @@ MidiTimeAxisView::~MidiTimeAxisView () { } +MidiStreamView* +MidiTimeAxisView::midi_view() +{ + return dynamic_cast(_view); +} + guint32 MidiTimeAxisView::show_at (double y, int& nth, Gtk::VBox *parent) { @@ -147,128 +152,149 @@ MidiTimeAxisView::hide () } void -MidiTimeAxisView::set_state (const XMLNode& node) +MidiTimeAxisView::append_extra_display_menu_items () { - const XMLProperty *prop; - - TimeAxisView::set_state (node); - - if ((prop = node.property ("shown_editor")) != 0) { - if (prop->value() == "no") { - _marked_for_display = false; - } else { - _marked_for_display = true; - } - } else { - _marked_for_display = true; - } + 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"); - XMLNodeList nlist = node.children(); - XMLNodeConstIterator niter; - XMLNode *child_node; + RadioMenuItem::Group range_group; + + range_items.push_back (RadioMenuElem (range_group, _("Show Full Range"), bind ( + mem_fun(*this, &MidiTimeAxisView::set_note_range), + MidiStreamView::FullRange))); - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - child_node = *niter; - - // uh... do stuff.. - } + range_items.push_back (RadioMenuElem (range_group, _("Fit Contents"), bind ( + mem_fun(*this, &MidiTimeAxisView::set_note_range), + MidiStreamView::ContentsRange))); + + ((Gtk::CheckMenuItem&)range_items.back()).set_active(true); + + items.push_back (MenuElem (_("Note range"), *range_menu)); } void -MidiTimeAxisView::build_display_menu () +MidiTimeAxisView::build_automation_action_menu () { using namespace Menu_Helpers; - /* get the size menu ready */ - - build_size_menu (); + RouteTimeAxisView::build_automation_action_menu (); - /* prepare it */ - - TimeAxisView::build_display_menu (); + MenuList& automation_items = automation_action_menu->items(); + + automation_items.push_back (SeparatorElem()); - /* now fill it with our stuff */ + automation_items.push_back (MenuElem (_("Controller..."), + mem_fun(*this, &MidiTimeAxisView::add_controller_track))); +} - MenuList& items = display_menu->items(); - display_menu->set_name ("ArdourContextMenu"); - - items.push_back (MenuElem (_("Height"), *size_menu)); - items.push_back (MenuElem (_("Color"), mem_fun(*this, &MidiTimeAxisView::select_track_color))); +Gtk::Menu* +MidiTimeAxisView::build_mode_menu() +{ + using namespace Menu_Helpers; + Menu* mode_menu = manage (new Menu); + MenuList& items = mode_menu->items(); + mode_menu->set_name ("ArdourContextMenu"); - items.push_back (SeparatorElem()); + RadioMenuItem::Group mode_group; + items.push_back (RadioMenuElem (mode_group, _("Sustained"), + bind (mem_fun (*this, &MidiTimeAxisView::set_note_mode), Sustained))); + _note_mode_item = dynamic_cast(&items.back()); + _note_mode_item->set_active(_note_mode == Sustained); - build_remote_control_menu (); - items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu)); + items.push_back (RadioMenuElem (mode_group, _("Percussive"), + bind (mem_fun (*this, &MidiTimeAxisView::set_note_mode), Percussive))); + _percussion_mode_item = dynamic_cast(&items.back()); + _percussion_mode_item->set_active(_note_mode == Percussive); - automation_action_menu = manage (new Menu); - MenuList& automation_items = automation_action_menu->items(); - automation_action_menu->set_name ("ArdourContextMenu"); + return mode_menu; +} - automation_items.push_back (SeparatorElem()); +void +MidiTimeAxisView::set_note_mode(NoteMode mode) +{ + if (_note_mode != mode) { + _note_mode = mode; + midi_track()->set_note_mode(mode); + _view->redisplay_diskstream(); + } +} - automation_items.push_back (MenuElem (_("Plugins"), subplugin_menu)); - if (is_midi_track()) { +void +MidiTimeAxisView::set_note_range(MidiStreamView::VisibleNoteRange range) +{ + //if (midi_view()->note_range() != range) { + midi_view()->set_note_range(range); + midi_view()->redisplay_diskstream(); + //} +} - 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, &MidiTimeAxisView::set_align_style), ExistingMaterial))); - align_existing_item = dynamic_cast(&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, &MidiTimeAxisView::set_align_style), CaptureTime))); - align_capture_item = dynamic_cast(&alignment_items.back()); - if (get_diskstream()->alignment_style() == CaptureTime) { - align_capture_item->set_active(); - } - - items.push_back (MenuElem (_("Alignment"), *alignment_menu)); +/** Prompt for a controller with a dialog and add an automation track for it + */ +void +MidiTimeAxisView::add_controller_track() +{ + int response; + Parameter param; - get_diskstream()->AlignmentStyleChanged.connect (mem_fun(*this, &MidiTimeAxisView::align_style_changed)); + { + AddMidiCCTrackDialog dialog; + dialog.set_transient_for(editor); + response = dialog.run(); + + if (response == Gtk::RESPONSE_ACCEPT) + param = dialog.parameter(); } - items.push_back (SeparatorElem()); - items.push_back (CheckMenuElem (_("Active"), mem_fun(*this, &RouteUI::toggle_route_active))); - route_active_menu_item = dynamic_cast (&items.back()); - route_active_menu_item->set_active (_route.active()); - - items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("Remove"), mem_fun(*this, &RouteUI::remove_this_route))); - + if (response == Gtk::RESPONSE_ACCEPT) + create_automation_child(param, true); } -// FIXME: duplicated in audio_time_axis.cc -/*static string -legalize_for_xml_node (string str) +void +MidiTimeAxisView::create_automation_child (Parameter param, bool show) { - string::size_type pos; - string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=:"; - string legal; + if (param.type() == MidiCCAutomation) { + + /* FIXME: don't create AutomationList for track itself */ - legal = str; - pos = 0; + boost::shared_ptr c = _route->control(param); - while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) { - legal.replace (pos, 1, "_"); - pos += 1; - } + if (!c) { + boost::shared_ptr al(new ARDOUR::AutomationList(param, 0, 127, 64)); + c = boost::shared_ptr(_route->control_factory(al)); + _route->add_control(c); + } + + boost::shared_ptr track(new AutomationTimeAxisView (_session, + _route, _route, c, + editor, + *this, + true, + parent_canvas, + _route->describe_parameter(param))); + + add_automation_child(param, track, show); - return legal; -}*/ + } else { + error << "MidiTimeAxisView: unknown automation child " << param.to_string() << endmsg; + } +} void MidiTimeAxisView::route_active_changed () { RouteUI::route_active_changed (); - if (is_midi_track()) { - if (_route.active()) { + if (is_track()) { + if (_route->active()) { controls_ebox.set_name ("MidiTrackControlsBaseUnselected"); controls_base_selected_name = "MidiTrackControlsBaseSelected"; controls_base_unselected_name = "MidiTrackControlsBaseUnselected"; @@ -278,7 +304,10 @@ MidiTimeAxisView::route_active_changed () controls_base_unselected_name = "MidiTrackControlsBaseInactiveUnselected"; } } else { - if (_route.active()) { + + throw; // wha? + + if (_route->active()) { controls_ebox.set_name ("BusControlsBaseUnselected"); controls_base_selected_name = "BusControlsBaseSelected"; controls_base_unselected_name = "BusControlsBaseUnselected"; @@ -290,9 +319,4 @@ MidiTimeAxisView::route_active_changed () } } -XMLNode* -MidiTimeAxisView::get_child_xml_node (const string & childname) -{ - return RouteUI::get_child_xml_node (childname); -}