a) start at creating ControlProtocol objects
[ardour.git] / gtk2_ardour / audio_time_axis.cc
index 0c0c402934181d461925f18e3719e5919e3deb35..6bb6fc45ceb4ac02227d333eb3217d0e2589e1f0 100644 (file)
@@ -84,21 +84,6 @@ using namespace LADSPA;
 using namespace Gtk;
 using namespace Editing;
 
-static const gchar * small_x_xpm[] = {
-"11 11 2 1",
-"      c None",
-".     c #000000",
-"           ",
-"           ",
-"  .     .  ",
-"   .   .   ",
-"    . .    ",
-"     .     ",
-"    . .    ",
-"   .   .   ",
-"  .     .  ",
-"           ",
-"           "};
 
 AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, Route& rt, Canvas& canvas)
        : AxisView(sess),
@@ -148,7 +133,7 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, Route& rt
        visual_button.set_name ("TrackVisualButton");
        hide_button.set_name ("TrackRemoveButton");
 
-       hide_button.add (*(manage (new Image (Gdk::Pixbuf::create_from_xpm_data(small_x_xpm)))));
+       hide_button.add (*(manage (new Image (get_xpm("small_x.xpm")))));
        
        _route.mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed));
        _route.solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
@@ -156,10 +141,19 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, Route& rt
 
        _route.panner().Changed.connect (mem_fun(*this, &AudioTimeAxisView::update_pans));
 
-       solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press));
-       solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release));
-       mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press));
-       mute_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::mute_release));
+       solo_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
+       mute_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
+       rec_enable_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
+       playlist_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
+       automation_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
+       size_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
+       visual_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
+       hide_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
+
+       solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press), false);
+       solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release), false);
+       mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press), false);
+       mute_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::mute_release), false);
        rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press));
        edit_group_button.signal_button_release_event().connect (mem_fun(*this, &AudioTimeAxisView::edit_click), false);
        playlist_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::playlist_click));
@@ -193,9 +187,8 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, Route& rt
        controls_table.attach (size_button, 2, 3, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
        controls_table.attach (automation_button, 3, 4, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
 
-       if (is_audio_track()) {
+       if (is_audio_track() && audio_track()->mode() == ARDOUR::Normal) {
                controls_table.attach (playlist_button, 5, 6, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
-
        }
 
        /* remove focus from the buttons */
@@ -338,29 +331,30 @@ AudioTimeAxisView::edit_click (GdkEventButton *ev)
        using namespace Menu_Helpers;
 
        MenuList& items = edit_group_menu.items ();
+       RadioMenuItem::Group group;
 
        items.clear ();
-       items.push_back (RadioMenuElem (edit_group_menu_radio_group, _("No group"), 
-                                  bind (mem_fun(*this, &AudioTimeAxisView::set_edit_group_from_menu), (RouteGroup *) 0)));
+       items.push_back (RadioMenuElem (group, _("No group"), 
+                                       bind (mem_fun(*this, &AudioTimeAxisView::set_edit_group_from_menu), (RouteGroup *) 0)));
        
        if (_route.edit_group() == 0) {
                static_cast<RadioMenuItem*>(&items.back())->set_active ();
        }
-
-       _session.foreach_edit_group (this, &AudioTimeAxisView::add_edit_group_menu_item);
+       
+       _session.foreach_edit_group (bind (mem_fun (*this, &AudioTimeAxisView::add_edit_group_menu_item), &group));
        edit_group_menu.popup (ev->button, ev->time);
 
        return FALSE;
 }
 
 void
-AudioTimeAxisView::add_edit_group_menu_item (RouteGroup *eg)
+AudioTimeAxisView::add_edit_group_menu_item (RouteGroup *eg, RadioMenuItem::Group* group)
 {
        using namespace Menu_Helpers;
 
        MenuList &items = edit_group_menu.items();
-       items.push_back (RadioMenuElem (edit_group_menu_radio_group,
-                                       eg->name(), bind (mem_fun(*this, &AudioTimeAxisView::set_edit_group_from_menu), eg)));
+
+       items.push_back (RadioMenuElem (*group, eg->name(), bind (mem_fun(*this, &AudioTimeAxisView::set_edit_group_from_menu), eg)));
        if (_route.edit_group() == eg) {
                static_cast<RadioMenuItem*>(&items.back())->set_active ();
        }
@@ -716,6 +710,8 @@ AudioTimeAxisView::build_display_menu ()
        items.push_back (MenuElem (_("Show all crossfades"), mem_fun(*this, &AudioTimeAxisView::show_all_xfades)));
        items.push_back (SeparatorElem());
 
+       build_remote_control_menu ();
+       items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu));
 
        automation_action_menu = manage (new Menu);
        MenuList& automation_items = automation_action_menu->items();
@@ -832,7 +828,7 @@ AudioTimeAxisView::rename_current_playlist ()
        AudioPlaylist *pl;
        DiskStream *ds;
 
-       if (((ds = get_diskstream()) == 0) ||((pl = ds->playlist()) == 0)) {
+       if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
                return;
        }
 
@@ -853,79 +849,79 @@ AudioTimeAxisView::rename_current_playlist ()
 }
 
 void
-AudioTimeAxisView::playlist_selected (AudioPlaylist *pl)
-{
-       DiskStream *ds;
-
-       if ((ds = get_diskstream()) != 0) {
-               ds->use_playlist (pl);
-       }
-}
-
-void
-AudioTimeAxisView::use_copy_playlist ()
+AudioTimeAxisView::use_copy_playlist (bool prompt)
 {
        AudioPlaylist *pl;
        DiskStream *ds;
        string name;
 
-       if (((ds = get_diskstream()) == 0) || ((pl = ds->playlist()) == 0)) {
+       if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
                return;
        }
        
-       ArdourPrompter prompter (true);
-       string new_name = Playlist::bump_name (pl->name(), _session);
-       
-       prompter.set_prompt (_("Name for playlist"));
-       prompter.set_initial_text (new_name);
-       prompter.show_all ();
+       name = Playlist::bump_name (pl->name(), _session);
 
-       switch (prompter.run ()) {
-       case Gtk::RESPONSE_ACCEPT:
-               prompter.get_result (name);
-               if (name.length()) {
-                       ds->use_copy_playlist ();
-                       pl = ds->playlist();
-                       pl->set_name (name);
+       if (prompt) {
+
+               ArdourPrompter prompter (true);
+               
+               prompter.set_prompt (_("Name for playlist"));
+               prompter.set_initial_text (name);
+               prompter.show_all ();
+               
+               switch (prompter.run ()) {
+               case Gtk::RESPONSE_ACCEPT:
+                       prompter.get_result (name);
+                       break;
+                       
+               default:
+                       return;
                }
-               break;
+       }
 
-       default:
-               break;
+       if (name.length()) {
+               ds->use_copy_playlist ();
+               pl = ds->playlist();
+               pl->set_name (name);
        }
 }
 
 void
-AudioTimeAxisView::use_new_playlist ()
+AudioTimeAxisView::use_new_playlist (bool prompt)
 {
        AudioPlaylist *pl;
        DiskStream *ds;
        string name;
 
-       if (((ds = get_diskstream()) == 0) || ((pl = ds->playlist()) == 0)) {
+       if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
                return;
        }
-
-       ArdourPrompter prompter (true);
-       string new_name = Playlist::bump_name (pl->name(), _session);
-
-       prompter.set_prompt (_("Name for playlist"));
-       prompter.set_initial_text (new_name);
        
-       switch (prompter.run ()) {
-       case Gtk::RESPONSE_ACCEPT:
-               prompter.get_result (name);
-               if (name.length()) {
-                       ds->use_new_playlist ();
-                       pl = ds->playlist();
-                       pl->set_name (name);
+       name = Playlist::bump_name (pl->name(), _session);
+
+       if (prompt) {
+               
+               ArdourPrompter prompter (true);
+               
+               prompter.set_prompt (_("Name for playlist"));
+               prompter.set_initial_text (name);
+               
+               switch (prompter.run ()) {
+               case Gtk::RESPONSE_ACCEPT:
+                       prompter.get_result (name);
+                       break;
+                       
+               default:
+                       return;
                }
-               break;
+       }
 
-       default:
-               break;
+       if (name.length()) {
+               ds->use_new_playlist ();
+               pl = ds->playlist();
+               pl->set_name (name);
        }
-}      
+}
 
 void
 AudioTimeAxisView::clear_playlist ()
@@ -1003,14 +999,19 @@ AudioTimeAxisView::selection_click (GdkEventButton* ev)
 {
        PublicEditor::TrackViewList* tracks = editor.get_valid_views (this, _route.edit_group());
 
-       if (Keyboard::modifier_state_contains (ev->state, Keyboard::Shift)) {
-               if (editor.get_selection().selected (this)) {
-                       editor.get_selection().remove (*tracks);
-               } else {
-                       editor.get_selection().add (*tracks);
-               }
-       } else {
+       switch (Keyboard::selection_type (ev->state)) {
+       case Selection::Toggle:
+               /* XXX this is not right */
+               editor.get_selection().add (*tracks);
+               break;
+               
+       case Selection::Set:
                editor.get_selection().set (*tracks);
+               break;
+
+       case Selection::Extend:
+               /* not defined yet */
+               break;
        }
 
        delete tracks;
@@ -1846,10 +1847,10 @@ AudioTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
        playlist_items.push_back (MenuElem (_("Rename"), mem_fun(*this, &AudioTimeAxisView::rename_current_playlist)));
        playlist_items.push_back (SeparatorElem());
 
-       playlist_items.push_back (MenuElem (_("New"), mem_fun(*this, &AudioTimeAxisView::use_new_playlist)));
-       playlist_items.push_back (MenuElem (_("New Copy"), mem_fun(*this, &AudioTimeAxisView::use_copy_playlist)));
+       playlist_items.push_back (MenuElem (_("New"), mem_fun(editor, &PublicEditor::new_playlists)));
+       playlist_items.push_back (MenuElem (_("New Copy"), mem_fun(editor, &PublicEditor::copy_playlists)));
        playlist_items.push_back (SeparatorElem());
-       playlist_items.push_back (MenuElem (_("Clear Current"), mem_fun(*this, &AudioTimeAxisView::clear_playlist)));
+       playlist_items.push_back (MenuElem (_("Clear Current"), mem_fun(editor, &PublicEditor::clear_playlists)));
        playlist_items.push_back (SeparatorElem());
        playlist_items.push_back (MenuElem(_("Select"), mem_fun(*this, &AudioTimeAxisView::show_playlist_selector)));
 
@@ -1968,3 +1969,10 @@ AudioTimeAxisView::color_handler (ColorID id, uint32_t val)
                break;
        }
 }
+
+bool
+AudioTimeAxisView::select_me (GdkEventButton* ev)
+{
+       editor.get_selection().add (this);
+       return false;
+}