Logo Search packages:      
Sourcecode: ardour version File versions  Download package

editor_route_list.cc

/*
    Copyright (C) 2000 Paul Davis 

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    $Id: editor_route_list.cc,v 1.40 2006/01/29 23:25:41 essej Exp $
*/

#include <algorithm>
#include <cstdlib>
#include <cmath>

#include "editor.h"
#include "ardour_ui.h"
#include "audio_time_axis.h"
#include "mixer_strip.h"
#include "gui_thread.h"

#include <ardour/route.h>

#include "i18n.h"

using namespace SigC;
using namespace ARDOUR;
using namespace Gtk;

void
Editor::handle_new_route_p (Route* route)
{
      ENSURE_GUI_THREAD(bind (slot (*this, &Editor::handle_new_route_p), route));
      handle_new_route (*route);
}

void
Editor::handle_new_route (Route& route)
{
      TimeAxisView *tv;
      AudioTimeAxisView *atv;
      const gchar *rowdata[1];

      if (route.hidden()) {
            return;
      }
            
      tv = new AudioTimeAxisView (*this, *session, route, track_canvas);

      track_views.push_back (tv);

      rowdata[0] = route.name ().c_str();

      ignore_route_list_reorder = true;
      route_list.rows().push_back (rowdata);
      route_list.rows().back().set_data (tv);
      if (tv->marked_for_display()) {
            route_list.rows().back().select();
      }

      if ((atv = dynamic_cast<AudioTimeAxisView*> (tv)) != 0) {
            /* added a new fresh one at the end */
            if (atv->route().order_key(N_("editor")) == -1) {
                  atv->route().set_order_key (N_("editor"), route_list.rows().size()-1);
            }
      }

      ignore_route_list_reorder = false;
      
      route.gui_changed.connect (slot (*this, &Editor::handle_gui_changes));

      tv->GoingAway.connect (bind (slot (*this, &Editor::remove_route), tv));
      
      ARDOUR_UI::instance()->editor_mixer_button().set_sensitive(true);
      
}

void
Editor::handle_gui_changes (string what, void *src)
{
      ENSURE_GUI_THREAD(bind (slot (*this, &Editor::handle_gui_changes), what, src));
      
      if (what == "track_height") {
            route_list_reordered ();
      }
}

void
Editor::remove_route (TimeAxisView *tv)
{
      ENSURE_GUI_THREAD(bind (slot (*this, &Editor::remove_route), tv));
      
      TrackViewList::iterator i;
      CList_Helpers::RowList::iterator ri;

      if ((i = find (track_views.begin(), track_views.end(), tv)) != track_views.end()) {
            track_views.erase (i);
      }

      for (ri  = route_list.rows().begin(); ri != route_list.rows().end(); ++ri) {
            if (tv == ri->get_data()) {
                  route_list.rows().erase (ri);
                  break;
            }
      }
      /* since the editor mixer goes away when you remove a route, set the
       * button to inacttive 
       */
      ARDOUR_UI::instance()->editor_mixer_button().set_active(false);

      /* and disable if all tracks and/or routes are gone */

      if (track_views.size() == 0) {
            ARDOUR_UI::instance()->editor_mixer_button().set_sensitive(false);
      }
}

void
Editor::route_name_changed (TimeAxisView *tv)
{
      CList_Helpers::RowList::iterator i;
      gint row;

      for (row = 0, i  = route_list.rows().begin(); i != route_list.rows().end(); ++i, ++row) {
            if (tv == i->get_data()) {
                  route_list.cell (row, 0).set_text (tv->name());
                  break;
            }
      }
}

void
Editor::route_list_selected (gint row, gint col, GdkEvent *ev)
{
      TimeAxisView *tv;
      if ((tv = (TimeAxisView *) route_list.get_row_data (row)) != 0) {
            tv->set_marked_for_display (true);
            route_list_reordered ();
      }
}

void
Editor::route_list_unselected (gint row, gint col, GdkEvent *ev)
{
      TimeAxisView *tv;
      AudioTimeAxisView *atv;

      if ((tv = (TimeAxisView *) route_list.get_row_data (row)) != 0) {

            tv->set_marked_for_display (false);

            if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
                  if (current_mixer_strip && &(atv->route()) == &(current_mixer_strip->route())) {
                        /* this will hide the mixer strip */
                        set_selected_mixer_strip(*atv);
                  }
            }

            route_list_reordered ();
      }
}

void
Editor::unselect_strip_in_display (TimeAxisView& tv)
{
      CList_Helpers::RowIterator i;

      if ((i = route_list.rows().find_data (&tv)) != route_list.rows().end()) {
            (*i).unselect ();
      }
}

void
Editor::select_strip_in_display (TimeAxisView& tv)
{
      CList_Helpers::RowIterator i;

      if ((i = route_list.rows().find_data (&tv)) != route_list.rows().end()) {
            (*i).select ();
      }
}

void
Editor::queue_route_list_reordered (gint arg1, gint arg2)

{
      /* the problem here is that we are called *before* the
         list has been reordered. so just queue up
         the actual re-drawer to happen once the re-ordering
         is complete.
      */

      Main::idle.connect (slot (*this, &Editor::route_list_reordered));
}

void
Editor::redisplay_route_list ()
{
      route_list_reordered ();
}

gint
Editor::route_list_reordered ()
{
      CList_Helpers::RowList::iterator i;
      gdouble y;
      int n;

      for (n = 0, y = 0, i  = route_list.rows().begin(); i != route_list.rows().end(); ++i) {

            TimeAxisView *tv = (TimeAxisView *) (*i)->get_data ();
            
            AudioTimeAxisView* at;
            
            if (!ignore_route_list_reorder) {
                  
                        /* this reorder is caused by user action, so reassign sort order keys
                           to tracks.
                        */
                  
                  if ((at = dynamic_cast<AudioTimeAxisView*> (tv)) != 0) {
                        at->route().set_order_key (N_("editor"), n);
                  }
            }
            
            if (tv->marked_for_display()) {
                  y += tv->show_at (y, n, &edit_controls_vbox);
                  y += track_spacing;
            } else {
                  tv->hide ();
            }
            
            n++;
      }

      edit_controls_scroller.queue_resize ();
      reset_scrolling_region ();

      //gtk_canvas_item_raise_to_top (time_line_group);
      gtk_canvas_item_raise_to_top (cursor_group);
      
      return FALSE;
}

void
Editor::hide_all_tracks (bool with_select)
{
      Gtk::CList_Helpers::RowList::iterator i;
      Gtk::CList_Helpers::RowList& rowlist = route_list.rows();
      
      route_list.freeze ();

      for (i = rowlist.begin(); i != rowlist.end(); ++i) {
            TimeAxisView *tv = (TimeAxisView *) i->get_data ();

            if (with_select) {
                  i->unselect ();
            } else {
                  tv->set_marked_for_display (false);
                  tv->hide();
            }
      }

      route_list.thaw ();

      reset_scrolling_region ();
}

void
Editor::route_list_column_click (gint col)
{
      if (route_list_menu == 0) {
            build_route_list_menu ();
      }

      route_list_menu->popup (0, 0);
}

void
Editor::build_route_list_menu ()
{
      using namespace Gtk::Menu_Helpers;

      route_list_menu = new Menu;
      
      MenuList& items = route_list_menu->items();
      route_list_menu->set_name ("ArdourContextMenu");

      items.push_back (MenuElem (_("Show All"), slot (*this, &Editor::select_all_routes)));
      items.push_back (MenuElem (_("Hide All"), slot (*this, &Editor::unselect_all_routes)));
      items.push_back (MenuElem (_("Show All AbstractTracks"), slot (*this, &Editor::select_all_audiotracks)));
      items.push_back (MenuElem (_("Hide All AbstractTracks"), slot (*this, &Editor::unselect_all_audiotracks)));
      items.push_back (MenuElem (_("Show All AudioBus"), slot (*this, &Editor::select_all_audiobus)));
      items.push_back (MenuElem (_("Hide All AudioBus"), slot (*this, &Editor::unselect_all_audiobus)));

}

void
Editor::unselect_all_routes ()
{
      hide_all_tracks (true);
}

void
Editor::select_all_routes ()

{
      CList_Helpers::RowList::iterator i;

      for (i = route_list.rows().begin(); i != route_list.rows().end(); ++i) {
            i->select ();
      }
}

void
Editor::select_all_audiotracks () 
{
      Gtk::CList_Helpers::RowList::iterator i;
      Gtk::CList_Helpers::RowList& rowlist = route_list.rows();
      
      route_list.freeze ();
      
      for (i = rowlist.begin(); i != rowlist.end(); ++i) {
            TimeAxisView *tv = (TimeAxisView *) i->get_data ();
            AudioTimeAxisView* atv;

            if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
                  if (atv->is_audio_track()) {
                        i->select ();
                  }
            }
      }
            
      route_list.thaw ();

}

void 
Editor::unselect_all_audiotracks () 
{
      Gtk::CList_Helpers::RowList::iterator i;
      Gtk::CList_Helpers::RowList& rowlist = route_list.rows();
      
      route_list.freeze ();

      for (i = rowlist.begin(); i != rowlist.end(); ++i) {
            TimeAxisView *tv = (TimeAxisView *) i->get_data ();
            AudioTimeAxisView* atv;

            if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
                  if (atv->is_audio_track()) {
                        i->unselect ();
                  }
            }
      }
      
      route_list.thaw ();

}

void
Editor::select_all_audiobus () 
{
      Gtk::CList_Helpers::RowList::iterator i;
      Gtk::CList_Helpers::RowList& rowlist = route_list.rows();
      
      route_list.freeze ();

      for (i = rowlist.begin(); i != rowlist.end(); ++i) {
            TimeAxisView *tv = (TimeAxisView *) i->get_data ();
            AudioTimeAxisView* atv;

            if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
                  if (!atv->is_audio_track()) {
                        i->select ();
                  }
            }
      }

      route_list.thaw ();

}

void
Editor::unselect_all_audiobus () 
{
      Gtk::CList_Helpers::RowList::iterator i;
      Gtk::CList_Helpers::RowList& rowlist = route_list.rows();
      
      route_list.freeze ();

      for (i = rowlist.begin(); i != rowlist.end(); ++i) {
            TimeAxisView *tv = (TimeAxisView *) i->get_data ();
            AudioTimeAxisView* atv;

            if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
                  if (!atv->is_audio_track()) {
                        i->unselect ();
                  }
            }
      }

      route_list.thaw ();

}

gint
route_list_compare_func (GtkCList* clist, gconstpointer a, gconstpointer b)
{
      TimeAxisView *tv1;
      TimeAxisView *tv2;
      AudioTimeAxisView *atv1;
      AudioTimeAxisView *atv2;
      Route* ra;
      Route* rb;

      GtkCListRow *row1 = (GtkCListRow *) a;
      GtkCListRow *row2 = (GtkCListRow *) b;

      tv1 = static_cast<TimeAxisView*> (row1->data);
      tv2 = static_cast<TimeAxisView*> (row2->data);

      if ((atv1 = dynamic_cast<AudioTimeAxisView*>(tv1)) == 0 ||
          (atv2 = dynamic_cast<AudioTimeAxisView*>(tv2)) == 0) {
            return FALSE;
      }

      ra = &atv1->route();
      rb = &atv2->route();

      /* use of ">" forces the correct sort order */

      return ra->order_key ("editor") > rb->order_key ("editor");
}


Generated by  Doxygen 1.6.0   Back to index